pipecraft 0.0.0-releaseit
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +35 -0
- package/.github/actions/calculate-version/action.yml +106 -0
- package/.github/actions/create-pr/action.yml +122 -0
- package/.github/actions/create-release/action.yml +74 -0
- package/.github/actions/create-tag/action.yml +94 -0
- package/.github/actions/detect-changes/action.yml +62 -0
- package/.github/actions/manage-branch/action.yml +113 -0
- package/.github/actions/promote-branch/action.yml +352 -0
- package/.github/example/workflows/job.analyze.code.yml +26 -0
- package/.github/example/workflows/job.analyze.docker.yml +32 -0
- package/.github/example/workflows/job.app.api.deploy.yml +127 -0
- package/.github/example/workflows/job.app.api.test.yml +102 -0
- package/.github/example/workflows/job.app.docs.deploy.yml +40 -0
- package/.github/example/workflows/job.app.docs.test.yml +50 -0
- package/.github/example/workflows/job.app.web.deploy.yml +96 -0
- package/.github/example/workflows/job.app.web.test.yml +49 -0
- package/.github/example/workflows/job.changes.yml +82 -0
- package/.github/example/workflows/job.create-pr.yml +96 -0
- package/.github/example/workflows/job.env-check.yml +43 -0
- package/.github/example/workflows/job.fast-forward.yml +103 -0
- package/.github/example/workflows/job.lint.yml +64 -0
- package/.github/example/workflows/job.pr-name.yml +70 -0
- package/.github/example/workflows/job.pr-squash-name.yml +27 -0
- package/.github/example/workflows/job.tag.yml +38 -0
- package/.github/example/workflows/job.version.yml +99 -0
- package/.github/example/workflows/lib.plugin-base.publish.yml +59 -0
- package/.github/example/workflows/pipe.yml +178 -0
- package/.github/example/workflows/scripts/fastforward.sh +51 -0
- package/.github/example/workflows/scripts/pipe-cleaner.sh +70 -0
- package/.github/scripts/fastforward.sh +51 -0
- package/.github/scripts/pipe-cleaner.sh +70 -0
- package/.github/workflows/pipeline.yml +220 -0
- package/.github/workflows/pr-title-check.yml +70 -0
- package/.github/workflows/publish.yml +39 -0
- package/.pipecraftrc.json +78 -0
- package/.release-it.cjs +71 -0
- package/PIPELINE_TESTING_PLAN.md +499 -0
- package/README.md +1101 -0
- package/TRUNK_FLOW_PLAN.md +401 -0
- package/assets/logo_banner.png +0 -0
- package/assets/logo_banner.webp +0 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +364 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/generators/init.tpl.d.ts +3 -0
- package/dist/generators/init.tpl.d.ts.map +1 -0
- package/dist/generators/init.tpl.js +117 -0
- package/dist/generators/init.tpl.js.map +1 -0
- package/dist/generators/workflows.tpl.d.ts +7 -0
- package/dist/generators/workflows.tpl.d.ts.map +1 -0
- package/dist/generators/workflows.tpl.js +73 -0
- package/dist/generators/workflows.tpl.js.map +1 -0
- package/dist/templates/actions/calculate-version.yml.tpl.d.ts +3 -0
- package/dist/templates/actions/calculate-version.yml.tpl.d.ts.map +1 -0
- package/dist/templates/actions/calculate-version.yml.tpl.js +122 -0
- package/dist/templates/actions/calculate-version.yml.tpl.js.map +1 -0
- package/dist/templates/actions/create-pr.yml.tpl.d.ts +3 -0
- package/dist/templates/actions/create-pr.yml.tpl.d.ts.map +1 -0
- package/dist/templates/actions/create-pr.yml.tpl.js +145 -0
- package/dist/templates/actions/create-pr.yml.tpl.js.map +1 -0
- package/dist/templates/actions/create-tag.yml.tpl.d.ts +3 -0
- package/dist/templates/actions/create-tag.yml.tpl.d.ts.map +1 -0
- package/dist/templates/actions/create-tag.yml.tpl.js +111 -0
- package/dist/templates/actions/create-tag.yml.tpl.js.map +1 -0
- package/dist/templates/actions/detect-changes.yml.tpl.d.ts +3 -0
- package/dist/templates/actions/detect-changes.yml.tpl.d.ts.map +1 -0
- package/dist/templates/actions/detect-changes.yml.tpl.js +79 -0
- package/dist/templates/actions/detect-changes.yml.tpl.js.map +1 -0
- package/dist/templates/actions/manage-branch.yml.tpl.d.ts +3 -0
- package/dist/templates/actions/manage-branch.yml.tpl.d.ts.map +1 -0
- package/dist/templates/actions/manage-branch.yml.tpl.js +130 -0
- package/dist/templates/actions/manage-branch.yml.tpl.js.map +1 -0
- package/dist/templates/actions/promote-branch.yml.tpl.d.ts +3 -0
- package/dist/templates/actions/promote-branch.yml.tpl.d.ts.map +1 -0
- package/dist/templates/actions/promote-branch.yml.tpl.js +362 -0
- package/dist/templates/actions/promote-branch.yml.tpl.js.map +1 -0
- package/dist/templates/workflows/pipeline-path-based.yml.tpl.d.ts +16 -0
- package/dist/templates/workflows/pipeline-path-based.yml.tpl.d.ts.map +1 -0
- package/dist/templates/workflows/pipeline-path-based.yml.tpl.js +652 -0
- package/dist/templates/workflows/pipeline-path-based.yml.tpl.js.map +1 -0
- package/dist/types/index.d.ts +63 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/ast-path-operations.d.ts +287 -0
- package/dist/utils/ast-path-operations.d.ts.map +1 -0
- package/dist/utils/ast-path-operations.js +419 -0
- package/dist/utils/ast-path-operations.js.map +1 -0
- package/dist/utils/config.d.ts +3 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +49 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/github-setup.d.ts +74 -0
- package/dist/utils/github-setup.d.ts.map +1 -0
- package/dist/utils/github-setup.js +418 -0
- package/dist/utils/github-setup.js.map +1 -0
- package/dist/utils/idempotency.d.ts +47 -0
- package/dist/utils/idempotency.d.ts.map +1 -0
- package/dist/utils/idempotency.js +176 -0
- package/dist/utils/idempotency.js.map +1 -0
- package/dist/utils/preflight.d.ts +55 -0
- package/dist/utils/preflight.d.ts.map +1 -0
- package/dist/utils/preflight.js +261 -0
- package/dist/utils/preflight.js.map +1 -0
- package/dist/utils/versioning.d.ts +41 -0
- package/dist/utils/versioning.d.ts.map +1 -0
- package/dist/utils/versioning.js +219 -0
- package/dist/utils/versioning.js.map +1 -0
- package/docs/USER_JOURNEY_ERRORS.md +352 -0
- package/eslint.config.js +77 -0
- package/examples/basic-config.json +41 -0
- package/examples/monorepo-config.json +49 -0
- package/examples/usage.md +289 -0
- package/package.json +58 -0
- package/scripts/debug-workflows.sh +339 -0
- package/scripts/parse-pipeline.js +29 -0
- package/scripts/test-job-order.cjs +140 -0
- package/scripts/validate-pipeline.cjs +379 -0
- package/scripts/verify-job-order.sh +30 -0
- package/src/cli/index.ts +414 -0
- package/src/generators/init.tpl.ts +126 -0
- package/src/generators/workflows.tpl.ts +80 -0
- package/src/templates/actions/calculate-version.yml.tpl.ts +124 -0
- package/src/templates/actions/create-pr.yml.tpl.ts +147 -0
- package/src/templates/actions/create-tag.yml.tpl.ts +112 -0
- package/src/templates/actions/detect-changes.yml.tpl.ts +87 -0
- package/src/templates/actions/manage-branch.yml.tpl.ts +132 -0
- package/src/templates/actions/promote-branch.yml.tpl.ts +364 -0
- package/src/templates/workflows/pipeline-path-based.yml.tpl.ts +706 -0
- package/src/types/index.ts +64 -0
- package/src/utils/README-ast-path-operations.md +390 -0
- package/src/utils/ast-path-operations.ts +581 -0
- package/src/utils/config.ts +64 -0
- package/src/utils/github-setup.ts +558 -0
- package/src/utils/idempotency.ts +215 -0
- package/src/utils/preflight.ts +306 -0
- package/src/utils/versioning.ts +244 -0
- package/tests/README.md +229 -0
- package/tests/TEST_STRUCTURE.md +256 -0
- package/tests/act/run-act-tests.sh +345 -0
- package/tests/debugging/debug-utils.ts +538 -0
- package/tests/debugging/debug-workflow.test.ts +339 -0
- package/tests/debugging/debug-workflows.sh +339 -0
- package/tests/debugging/iterative-debug.ts +652 -0
- package/tests/debugging/run-debug-tests.sh +431 -0
- package/tests/fixtures/basic-config.json +51 -0
- package/tests/fixtures/invalid-config.json +9 -0
- package/tests/fixtures/pipeline-generated.yml +235 -0
- package/tests/fixtures/pipeline-preserve-comments.yml +245 -0
- package/tests/fixtures/pipeline-user-modified.yml +245 -0
- package/tests/fixtures/test-config.json +58 -0
- package/tests/github-live/README.md +250 -0
- package/tests/github-local/JOB_WORKFLOW_TESTS.md +296 -0
- package/tests/github-local/README.md +240 -0
- package/tests/github-local/run-all-tests.sh +422 -0
- package/tests/github-local/test-job-workflows.sh +631 -0
- package/tests/github-local/test-pipeline-workflow.sh +440 -0
- package/tests/integration/generators.test.ts +578 -0
- package/tests/integration/path-based-template.test.ts +510 -0
- package/tests/integration/simple-path-based.test.ts +415 -0
- package/tests/setup.ts +56 -0
- package/tests/unit/ast-path-operations-extended.test.ts +302 -0
- package/tests/unit/cli.test.ts +541 -0
- package/tests/unit/config-extended.test.ts +412 -0
- package/tests/unit/config.test.ts +152 -0
- package/tests/unit/github-setup.test.ts +189 -0
- package/tests/unit/idempotency-isolated.test.ts +297 -0
- package/tests/unit/job-order.test.ts +157 -0
- package/tests/unit/pipeline-path-based.test.ts +511 -0
- package/tests/unit/validate-pipeline.test.ts +384 -0
- package/tests/unit/versioning-extended.test.ts +279 -0
- package/tests/unit/versioning.test.ts +241 -0
- package/tsconfig.debug.json +17 -0
- package/tsconfig.json +28 -0
- package/vitest.config.ts +51 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(test:*)",
|
|
5
|
+
"Bash(git commit -m \"$(cat <<''EOF''\nrefactor: rename project from FlowCraft to PipeCraft\n\nRename the entire project to PipeCraft to better align with the -craft naming convention (matching pullcraft). The new name emphasizes pipeline crafting and CI/CD automation.\n\nChanges:\n- Rename package from ''flowcraft'' to ''pipecraft''\n- Rename CLI command from ''flowcraft'' to ''pipecraft''\n- Rename config file from .flowcraftrc.json to .pipecraftrc.json\n- Update all documentation and branding\n- Update all source code references\n- Update all test files\n- Update all script files\n- Update GitHub Actions setup messaging\n\nThe functionality remains identical - only the branding has changed.\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nEOF\n)\")",
|
|
6
|
+
"Bash(git rev-parse:*)",
|
|
7
|
+
"Bash(gh run list:*)",
|
|
8
|
+
"Bash(gh workflow list:*)",
|
|
9
|
+
"Bash(gh run view:*)",
|
|
10
|
+
"Bash(git fetch:*)",
|
|
11
|
+
"Bash(pnpm build)",
|
|
12
|
+
"Bash(node:*)",
|
|
13
|
+
"Bash(pnpm pipecraft generate:*)",
|
|
14
|
+
"Bash(git restore:*)",
|
|
15
|
+
"Bash(git add:*)",
|
|
16
|
+
"Bash(git commit -m \"$(cat <<''EOF''\nfeat: add per-branch autoMerge configuration for hybrid manual/auto workflow\n\nAdd support for configurable auto-merge behavior per target branch, allowing\nteams to choose when to automatically fast-forward branches vs requiring manual\nPR review.\n\nChanges:\n- Add autoMerge config option supporting both boolean and per-branch object\n- Update pipeline template to conditionally generate branch job based on config\n- Add branch output to manage-branch action for workflow triggering\n- Implement workflow dispatch triggering to run pipeline on target branch\n- Add logic to remove branch job when autoMerge is disabled\n\nConfiguration:\n- Set autoMerge per target branch in .pipecraftrc.json\n- Example: { \"staging\": true, \"main\": false }\n- Enables auto-merge to staging, manual review for production\n\nWorkflow behavior:\n- When autoMerge enabled: creates PR + auto fast-forward + triggers workflow\n- When autoMerge disabled: creates PR + waits for manual merge (human merge triggers workflow)\n- Uses GITHUB_TOKEN with gh workflow run (no PAT needed)\n- Branch job includes conditional if statement based on source branch\n\nThis solves the issue where GITHUB_TOKEN pushes don''t trigger workflows by\nexplicitly triggering them, while maintaining flexibility for manual review\nwhen needed (e.g., before production deploys).\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nEOF\n)\")",
|
|
17
|
+
"Bash(git push:*)",
|
|
18
|
+
"Bash(git commit:*)",
|
|
19
|
+
"Bash(gh pr list:*)",
|
|
20
|
+
"Bash(cat:*)",
|
|
21
|
+
"Read(//private/tmp/**)",
|
|
22
|
+
"Bash(pnpm test:*)",
|
|
23
|
+
"Bash(/dev/null)",
|
|
24
|
+
"Bash(gh api:*)",
|
|
25
|
+
"Bash(gh pr merge:*)",
|
|
26
|
+
"Bash(xargs -I {} git show {}:.github/workflows/pipeline.yml)",
|
|
27
|
+
"Bash(git checkout:*)",
|
|
28
|
+
"Bash(npm test)",
|
|
29
|
+
"Bash(pkill:*)",
|
|
30
|
+
"Bash(npm run build)"
|
|
31
|
+
],
|
|
32
|
+
"deny": [],
|
|
33
|
+
"ask": []
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
name: 'Calculate Version'
|
|
2
|
+
description: 'Calculate semantic version using release-it and conventional commits'
|
|
3
|
+
author: 'Pipecraft'
|
|
4
|
+
|
|
5
|
+
inputs:
|
|
6
|
+
baseRef:
|
|
7
|
+
description: 'Base reference for version calculation'
|
|
8
|
+
required: false
|
|
9
|
+
default: 'main'
|
|
10
|
+
|
|
11
|
+
outputs:
|
|
12
|
+
version:
|
|
13
|
+
description: 'The determined version'
|
|
14
|
+
value: ${{ steps.set_version.outputs.version }}
|
|
15
|
+
|
|
16
|
+
runs:
|
|
17
|
+
using: 'composite'
|
|
18
|
+
steps:
|
|
19
|
+
- name: Checkout Code
|
|
20
|
+
uses: actions/checkout@v4
|
|
21
|
+
with:
|
|
22
|
+
fetch-depth: 0
|
|
23
|
+
|
|
24
|
+
- name: Install Node.js
|
|
25
|
+
uses: actions/setup-node@v4
|
|
26
|
+
with:
|
|
27
|
+
node-version: 22
|
|
28
|
+
|
|
29
|
+
- name: Configure Git
|
|
30
|
+
shell: bash
|
|
31
|
+
run: |
|
|
32
|
+
git config --global user.name "github-actions[bot]"
|
|
33
|
+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
34
|
+
|
|
35
|
+
- name: Get existing version tag
|
|
36
|
+
id: get_version_old
|
|
37
|
+
shell: bash
|
|
38
|
+
run: |
|
|
39
|
+
set -x # Enable debugging output
|
|
40
|
+
# Get the current commit hash
|
|
41
|
+
git rev-parse HEAD
|
|
42
|
+
COMMIT_HASH=$(git rev-parse HEAD)
|
|
43
|
+
echo "Current commit hash: $COMMIT_HASH"
|
|
44
|
+
|
|
45
|
+
# Check for tags on the current commit
|
|
46
|
+
TAG=$(git tag --points-at $COMMIT_HASH | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+\$' || true)
|
|
47
|
+
echo "Tags found: $TAG"
|
|
48
|
+
|
|
49
|
+
if [ -z "$TAG" ]; then
|
|
50
|
+
echo "No existing tag found on the current commit"
|
|
51
|
+
else
|
|
52
|
+
echo "Found existing tag: $TAG"
|
|
53
|
+
echo "version=$TAG" >> $GITHUB_OUTPUT
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
- name: Set up minimal package.json
|
|
57
|
+
shell: bash
|
|
58
|
+
run: |
|
|
59
|
+
echo '{
|
|
60
|
+
"name": "temporary-lib",
|
|
61
|
+
"version": "0.0.0-release-it"
|
|
62
|
+
}' > package.json
|
|
63
|
+
|
|
64
|
+
- name: Install dependencies
|
|
65
|
+
shell: bash
|
|
66
|
+
run: npm install @release-it/conventional-changelog conventional-changelog-angular
|
|
67
|
+
|
|
68
|
+
- name: Get version
|
|
69
|
+
if: steps.get_version_old.outputs.version == ''
|
|
70
|
+
id: get_version_new
|
|
71
|
+
shell: bash
|
|
72
|
+
run: |
|
|
73
|
+
# Get version and filter out warnings
|
|
74
|
+
RAW_OUTPUT=$(npx release-it --ci --release-version 2>&1 || echo "")
|
|
75
|
+
# Extract just the version number (last line that looks like a version)
|
|
76
|
+
VERSION=$(echo "$RAW_OUTPUT" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+' | tail -1 || true)
|
|
77
|
+
|
|
78
|
+
if [[ "$RAW_OUTPUT" == *"No new version to release"* || -z "$VERSION" ]]; then
|
|
79
|
+
echo "No new version to release"
|
|
80
|
+
echo "VERSION=" >> $GITHUB_ENV
|
|
81
|
+
echo "version=" >> $GITHUB_OUTPUT
|
|
82
|
+
else
|
|
83
|
+
echo "New version to release: $VERSION"
|
|
84
|
+
echo "VERSION=v$VERSION" >> $GITHUB_ENV
|
|
85
|
+
echo "version=v$VERSION" >> $GITHUB_OUTPUT
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
- name: Set version output
|
|
89
|
+
id: set_version
|
|
90
|
+
shell: bash
|
|
91
|
+
run: |
|
|
92
|
+
if [ -n "${{ steps.get_version_old.outputs.version }}" ]; then
|
|
93
|
+
echo "Using old version: ${{ steps.get_version_old.outputs.version }}"
|
|
94
|
+
echo "version=${{ steps.get_version_old.outputs.version }}" >> $GITHUB_OUTPUT
|
|
95
|
+
elif [ -n "${{ steps.get_version_new.outputs.version }}" ]; then
|
|
96
|
+
echo "Using new version: ${{ steps.get_version_new.outputs.version }}"
|
|
97
|
+
echo "version=${{ steps.get_version_new.outputs.version }}" >> $GITHUB_OUTPUT
|
|
98
|
+
else
|
|
99
|
+
echo "No version determined"
|
|
100
|
+
echo "version=" >> $GITHUB_OUTPUT
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
- name: Output version
|
|
104
|
+
shell: bash
|
|
105
|
+
run: |
|
|
106
|
+
echo "Version determined: ${{ steps.set_version.outputs.version }}"
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
name: 'Create Pull Request'
|
|
2
|
+
description: 'Create a pull request between source and target branches'
|
|
3
|
+
author: 'Pipecraft'
|
|
4
|
+
|
|
5
|
+
inputs:
|
|
6
|
+
sourceBranch:
|
|
7
|
+
description: 'Source branch for the PR'
|
|
8
|
+
required: true
|
|
9
|
+
targetBranch:
|
|
10
|
+
description: 'Target branch for the PR'
|
|
11
|
+
required: true
|
|
12
|
+
title:
|
|
13
|
+
description: 'Title for the PR'
|
|
14
|
+
required: true
|
|
15
|
+
body:
|
|
16
|
+
description: 'Body/description for the PR'
|
|
17
|
+
required: false
|
|
18
|
+
labels:
|
|
19
|
+
description: 'Comma-separated list of labels'
|
|
20
|
+
required: false
|
|
21
|
+
token:
|
|
22
|
+
description: 'GitHub token for authentication'
|
|
23
|
+
required: false
|
|
24
|
+
default: ${{ github.token }}
|
|
25
|
+
|
|
26
|
+
outputs:
|
|
27
|
+
prNumber:
|
|
28
|
+
description: 'The created PR number'
|
|
29
|
+
value: ${{ steps.create-pr.outputs.prNumber }}
|
|
30
|
+
prUrl:
|
|
31
|
+
description: 'The created PR URL'
|
|
32
|
+
value: ${{ steps.create-pr.outputs.prUrl }}
|
|
33
|
+
|
|
34
|
+
runs:
|
|
35
|
+
using: 'composite'
|
|
36
|
+
steps:
|
|
37
|
+
- name: Checkout Code
|
|
38
|
+
uses: actions/checkout@v4
|
|
39
|
+
with:
|
|
40
|
+
fetch-depth: 0
|
|
41
|
+
token: ${{ inputs.token }}
|
|
42
|
+
|
|
43
|
+
- name: Check if PR Already Exists
|
|
44
|
+
id: check-existing-pr
|
|
45
|
+
shell: bash
|
|
46
|
+
run: |
|
|
47
|
+
SOURCE="${{ inputs.sourceBranch }}"
|
|
48
|
+
TARGET="${{ inputs.targetBranch }}"
|
|
49
|
+
|
|
50
|
+
# Check if PR already exists
|
|
51
|
+
EXISTING_PR=$(gh pr list --head "$SOURCE" --base "$TARGET" --json number --jq '.[0].number' 2>/dev/null || echo "")
|
|
52
|
+
|
|
53
|
+
if [ -n "$EXISTING_PR" ]; then
|
|
54
|
+
echo "exists=true" >> $GITHUB_OUTPUT
|
|
55
|
+
echo "pr_number=$EXISTING_PR" >> $GITHUB_OUTPUT
|
|
56
|
+
echo "⚠️ PR already exists: #$EXISTING_PR"
|
|
57
|
+
else
|
|
58
|
+
echo "exists=false" >> $GITHUB_OUTPUT
|
|
59
|
+
echo "✅ No existing PR found"
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
- name: Create Pull Request
|
|
63
|
+
if: steps.check-existing-pr.outputs.exists == 'false'
|
|
64
|
+
id: create-pr
|
|
65
|
+
shell: bash
|
|
66
|
+
run: |
|
|
67
|
+
SOURCE="${{ inputs.sourceBranch }}"
|
|
68
|
+
TARGET="${{ inputs.targetBranch }}"
|
|
69
|
+
TITLE="${{ inputs.title }}"
|
|
70
|
+
BODY="${{ inputs.body }}"
|
|
71
|
+
LABELS="${{ inputs.labels }}"
|
|
72
|
+
|
|
73
|
+
# Prepare labels array
|
|
74
|
+
LABEL_ARGS=""
|
|
75
|
+
if [ -n "$LABELS" ]; then
|
|
76
|
+
IFS=',' read -ra LABEL_ARRAY <<< "$LABELS"
|
|
77
|
+
for label in "${LABEL_ARRAY[@]}"; do
|
|
78
|
+
LABEL_ARGS="$LABEL_ARGS --label \"${label// /}\""
|
|
79
|
+
done
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
# Create the PR
|
|
83
|
+
PR_OUTPUT=$(gh pr create \--title "$TITLE" \--body "$BODY" \--head "$SOURCE" \--base "$TARGET" \$LABEL_ARGS \--json number,url --jq '.number,.url' 2>&1)
|
|
84
|
+
|
|
85
|
+
if echo "$PR_OUTPUT" | grep -q '"number":'; then
|
|
86
|
+
PR_NUMBER=$(echo "$PR_OUTPUT" | jq -r '.number')
|
|
87
|
+
PR_URL=$(echo "$PR_OUTPUT" | jq -r '.url')
|
|
88
|
+
echo "prNumber=$PR_NUMBER" >> $GITHUB_OUTPUT
|
|
89
|
+
echo "prUrl=$PR_URL" >> $GITHUB_OUTPUT
|
|
90
|
+
echo "✅ Created PR #$PR_NUMBER"
|
|
91
|
+
echo "🔗 URL: $PR_URL"
|
|
92
|
+
else
|
|
93
|
+
echo "❌ Failed to create PR"
|
|
94
|
+
echo "Error output:"
|
|
95
|
+
echo "$PR_OUTPUT"
|
|
96
|
+
exit 1
|
|
97
|
+
fi
|
|
98
|
+
|
|
99
|
+
- name: Use Existing PR
|
|
100
|
+
if: steps.check-existing-pr.outputs.exists == 'true'
|
|
101
|
+
id: use-existing-pr
|
|
102
|
+
shell: bash
|
|
103
|
+
run: |
|
|
104
|
+
PR_NUMBER="${{ steps.check-existing-pr.outputs.pr_number }}"
|
|
105
|
+
PR_URL="https://github.com/${{ github.repository }}/pull/$PR_NUMBER"
|
|
106
|
+
echo "prNumber=$PR_NUMBER" >> $GITHUB_OUTPUT
|
|
107
|
+
echo "prUrl=$PR_URL" >> $GITHUB_OUTPUT
|
|
108
|
+
echo "✅ Using existing PR #$PR_NUMBER"
|
|
109
|
+
echo "🔗 URL: $PR_URL"
|
|
110
|
+
|
|
111
|
+
- name: Action Summary
|
|
112
|
+
shell: bash
|
|
113
|
+
run: |
|
|
114
|
+
if [ "${{ steps.create-pr.outputs.prNumber }}" != "" ]; then
|
|
115
|
+
echo "✅ Successfully created PR #${{ steps.create-pr.outputs.prNumber }}"
|
|
116
|
+
echo "🔗 URL: ${{ steps.create-pr.outputs.prUrl }}"
|
|
117
|
+
elif [ "${{ steps.use-existing-pr.outputs.prNumber }}" != "" ]; then
|
|
118
|
+
echo "ℹ️ Using existing PR #${{ steps.use-existing-pr.outputs.prNumber }}"
|
|
119
|
+
echo "🔗 URL: ${{ steps.use-existing-pr.outputs.prUrl }}"
|
|
120
|
+
else
|
|
121
|
+
echo "❌ No PR created or found"
|
|
122
|
+
fi
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
name: 'Create Release'
|
|
2
|
+
description: 'Create a GitHub release with auto-generated release notes'
|
|
3
|
+
author: 'PipeCraft'
|
|
4
|
+
|
|
5
|
+
inputs:
|
|
6
|
+
version:
|
|
7
|
+
description: 'Version to release (e.g., v1.2.3)'
|
|
8
|
+
required: true
|
|
9
|
+
token:
|
|
10
|
+
description: 'GitHub token for authentication'
|
|
11
|
+
required: false
|
|
12
|
+
default: ${{ github.token }}
|
|
13
|
+
|
|
14
|
+
outputs:
|
|
15
|
+
release_url:
|
|
16
|
+
description: 'The URL of the created release'
|
|
17
|
+
value: ${{ steps.create.outputs.release_url }}
|
|
18
|
+
release_id:
|
|
19
|
+
description: 'The ID of the created release'
|
|
20
|
+
value: ${{ steps.create.outputs.release_id }}
|
|
21
|
+
|
|
22
|
+
runs:
|
|
23
|
+
using: 'composite'
|
|
24
|
+
steps:
|
|
25
|
+
- name: Checkout Code
|
|
26
|
+
uses: actions/checkout@v4
|
|
27
|
+
with:
|
|
28
|
+
fetch-depth: 0
|
|
29
|
+
token: ${{ inputs.token }}
|
|
30
|
+
|
|
31
|
+
- name: Create GitHub Release
|
|
32
|
+
id: create
|
|
33
|
+
shell: bash
|
|
34
|
+
env:
|
|
35
|
+
GH_TOKEN: ${{ inputs.token }}
|
|
36
|
+
run: |
|
|
37
|
+
VERSION="${{ inputs.version }}"
|
|
38
|
+
echo "📦 Creating GitHub release for $VERSION"
|
|
39
|
+
|
|
40
|
+
# Generate release notes from commits since last tag
|
|
41
|
+
PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
|
|
42
|
+
|
|
43
|
+
if [ -n "$PREVIOUS_TAG" ]; then
|
|
44
|
+
echo "📝 Generating release notes from $PREVIOUS_TAG to HEAD"
|
|
45
|
+
RELEASE_NOTES=$(git log $PREVIOUS_TAG..HEAD --pretty=format:"- %s" --no-merges)
|
|
46
|
+
else
|
|
47
|
+
echo "📝 Generating release notes from all commits"
|
|
48
|
+
RELEASE_NOTES=$(git log --pretty=format:"- %s" --no-merges)
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# Create release with notes
|
|
52
|
+
RELEASE_OUTPUT=$(gh release create "$VERSION" \
|
|
53
|
+
--title "Release $VERSION" \
|
|
54
|
+
--notes "$RELEASE_NOTES" \
|
|
55
|
+
--latest 2>&1)
|
|
56
|
+
|
|
57
|
+
RELEASE_EXIT_CODE=$?
|
|
58
|
+
|
|
59
|
+
if [ $RELEASE_EXIT_CODE -eq 0 ]; then
|
|
60
|
+
# Extract release URL from output
|
|
61
|
+
RELEASE_URL=$(echo "$RELEASE_OUTPUT" | grep -oE 'https://github.com/.*/releases/.*')
|
|
62
|
+
echo "release_url=$RELEASE_URL" >> $GITHUB_OUTPUT
|
|
63
|
+
|
|
64
|
+
# Get release ID using gh api
|
|
65
|
+
RELEASE_ID=$(gh api repos/${{ github.repository }}/releases/tags/$VERSION --jq '.id')
|
|
66
|
+
echo "release_id=$RELEASE_ID" >> $GITHUB_OUTPUT
|
|
67
|
+
|
|
68
|
+
echo "✅ Release created successfully"
|
|
69
|
+
echo "🔗 URL: $RELEASE_URL"
|
|
70
|
+
else
|
|
71
|
+
echo "❌ Failed to create release"
|
|
72
|
+
echo "$RELEASE_OUTPUT"
|
|
73
|
+
exit 1
|
|
74
|
+
fi
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
name: 'Tag Version'
|
|
2
|
+
description: 'Create and push a Git tag for a given version'
|
|
3
|
+
author: 'Pipecraft'
|
|
4
|
+
|
|
5
|
+
inputs:
|
|
6
|
+
version:
|
|
7
|
+
description: 'Version to tag'
|
|
8
|
+
required: true
|
|
9
|
+
tag_prefix:
|
|
10
|
+
description: 'Prefix for the tag (e.g., v)'
|
|
11
|
+
required: false
|
|
12
|
+
default: 'v'
|
|
13
|
+
push:
|
|
14
|
+
description: 'Whether to push the tag to remote'
|
|
15
|
+
required: false
|
|
16
|
+
default: 'true'
|
|
17
|
+
|
|
18
|
+
outputs:
|
|
19
|
+
tag_name:
|
|
20
|
+
description: 'The created tag name'
|
|
21
|
+
value: ${{ steps.tag.outputs.tag_name }}
|
|
22
|
+
success:
|
|
23
|
+
description: 'Whether the tag was created successfully'
|
|
24
|
+
value: ${{ steps.tag.outputs.success }}
|
|
25
|
+
|
|
26
|
+
runs:
|
|
27
|
+
using: 'composite'
|
|
28
|
+
steps:
|
|
29
|
+
- name: Validate Inputs
|
|
30
|
+
id: validate
|
|
31
|
+
shell: bash
|
|
32
|
+
run: |
|
|
33
|
+
if [ -z "${{ inputs.version }}" ]; then
|
|
34
|
+
echo "❌ Version is required"
|
|
35
|
+
exit 1
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# Strip v prefix if present and validate version format
|
|
39
|
+
VERSION="${{ inputs.version }}"
|
|
40
|
+
VERSION="${VERSION#v}" # Remove v prefix
|
|
41
|
+
|
|
42
|
+
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
43
|
+
echo "❌ Version must be in format [v]x.y.z (e.g., 1.0.0 or v1.0.0)"
|
|
44
|
+
exit 1
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
echo "✅ Version format is valid: $VERSION"
|
|
48
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
49
|
+
|
|
50
|
+
- name: Configure Git
|
|
51
|
+
shell: bash
|
|
52
|
+
run: |
|
|
53
|
+
git config user.name "github-actions[bot]"
|
|
54
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
55
|
+
|
|
56
|
+
- name: Create Tag
|
|
57
|
+
id: tag
|
|
58
|
+
shell: bash
|
|
59
|
+
run: |
|
|
60
|
+
VERSION="${{ steps.validate.outputs.version }}"
|
|
61
|
+
PREFIX="${{ inputs.tag_prefix }}"
|
|
62
|
+
TAG_NAME="${PREFIX}${VERSION}"
|
|
63
|
+
|
|
64
|
+
# Check if tag already exists
|
|
65
|
+
if git tag -l | grep -q "^${TAG_NAME}$"; then
|
|
66
|
+
echo "⚠️ Tag ${TAG_NAME} already exists"
|
|
67
|
+
echo "tag_name=${TAG_NAME}" >> $GITHUB_OUTPUT
|
|
68
|
+
echo "success=false" >> $GITHUB_OUTPUT
|
|
69
|
+
exit 0
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# Create the tag
|
|
73
|
+
git tag -a "${TAG_NAME}" -m "Release ${TAG_NAME}"
|
|
74
|
+
echo "✅ Created tag: ${TAG_NAME}"
|
|
75
|
+
|
|
76
|
+
echo "tag_name=${TAG_NAME}" >> $GITHUB_OUTPUT
|
|
77
|
+
echo "success=true" >> $GITHUB_OUTPUT
|
|
78
|
+
|
|
79
|
+
- name: Push Tag
|
|
80
|
+
if: steps.tag.outputs.success == 'true' && inputs.push == 'true'
|
|
81
|
+
shell: bash
|
|
82
|
+
run: |
|
|
83
|
+
TAG_NAME="${{ steps.tag.outputs.tag_name }}"
|
|
84
|
+
git push origin "${TAG_NAME}"
|
|
85
|
+
echo "✅ Pushed tag ${TAG_NAME} to remote"
|
|
86
|
+
|
|
87
|
+
- name: Action Summary
|
|
88
|
+
shell: bash
|
|
89
|
+
run: |
|
|
90
|
+
if [ "${{ steps.tag.outputs.success }}" == "true" ]; then
|
|
91
|
+
echo "✅ Successfully created and pushed tag: ${{ steps.tag.outputs.tag_name }}"
|
|
92
|
+
else
|
|
93
|
+
echo "❌ Failed to create tag: ${{ steps.tag.outputs.tag_name }}"
|
|
94
|
+
fi
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
name: 'Detect Changes'
|
|
2
|
+
description: 'Detect changes in different application domains based on file paths'
|
|
3
|
+
author: 'Pipecraft'
|
|
4
|
+
|
|
5
|
+
inputs:
|
|
6
|
+
baseRef:
|
|
7
|
+
description: 'Base reference to compare against'
|
|
8
|
+
required: false
|
|
9
|
+
default: 'main'
|
|
10
|
+
|
|
11
|
+
outputs:
|
|
12
|
+
core:
|
|
13
|
+
description: 'Whether core domain has changes'
|
|
14
|
+
value: ${{ steps.merge.outputs.core }}
|
|
15
|
+
test:
|
|
16
|
+
description: 'Whether test domain has changes'
|
|
17
|
+
value: ${{ steps.merge.outputs.test }}
|
|
18
|
+
cicd:
|
|
19
|
+
description: 'Whether cicd domain has changes'
|
|
20
|
+
value: ${{ steps.merge.outputs.cicd }}
|
|
21
|
+
|
|
22
|
+
runs:
|
|
23
|
+
using: 'composite'
|
|
24
|
+
steps:
|
|
25
|
+
- name: Checkout Code
|
|
26
|
+
uses: actions/checkout@v4
|
|
27
|
+
with:
|
|
28
|
+
fetch-depth: 0
|
|
29
|
+
|
|
30
|
+
- name: Set Base Branch
|
|
31
|
+
id: set-base
|
|
32
|
+
shell: bash
|
|
33
|
+
run: |
|
|
34
|
+
base_branch=${{ inputs.baseRef || 'main' }}
|
|
35
|
+
echo "base_branch=$base_branch" >> $GITHUB_OUTPUT
|
|
36
|
+
echo "base_branch=$base_branch" >> $GITHUB_ENV
|
|
37
|
+
|
|
38
|
+
- name: Detect Changes
|
|
39
|
+
uses: dorny/paths-filter@v3
|
|
40
|
+
id: filter
|
|
41
|
+
with:
|
|
42
|
+
base: ${{ steps.set-base.outputs.base_branch }}
|
|
43
|
+
filters: |
|
|
44
|
+
core:
|
|
45
|
+
- 'src/**'
|
|
46
|
+
test:
|
|
47
|
+
- 'tests/**'
|
|
48
|
+
cicd:
|
|
49
|
+
- '.github/**'
|
|
50
|
+
|
|
51
|
+
- name: Merge filter outputs
|
|
52
|
+
id: merge
|
|
53
|
+
shell: bash
|
|
54
|
+
run: |
|
|
55
|
+
echo "core=${{ contains(steps.filter.outputs.changes, 'core') }}" >> $GITHUB_OUTPUT
|
|
56
|
+
echo "test=${{ contains(steps.filter.outputs.changes, 'test') }}" >> $GITHUB_OUTPUT
|
|
57
|
+
echo "cicd=${{ contains(steps.filter.outputs.changes, 'cicd') }}" >> $GITHUB_OUTPUT
|
|
58
|
+
|
|
59
|
+
echo "📋 Change Detection Results:"
|
|
60
|
+
echo " core: ${{ contains(steps.filter.outputs.changes, 'core') }}"
|
|
61
|
+
echo " test: ${{ contains(steps.filter.outputs.changes, 'test') }}"
|
|
62
|
+
echo " cicd: ${{ contains(steps.filter.outputs.changes, 'cicd') }}"
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
name: 'Branch Management'
|
|
2
|
+
description: 'Manage branches (fast-forward, create, delete)'
|
|
3
|
+
author: 'Pipecraft'
|
|
4
|
+
|
|
5
|
+
inputs:
|
|
6
|
+
action:
|
|
7
|
+
description: 'Action to perform (fast-forward, create, delete)'
|
|
8
|
+
required: true
|
|
9
|
+
targetBranch:
|
|
10
|
+
description: 'Target branch for the action'
|
|
11
|
+
required: true
|
|
12
|
+
sourceBranch:
|
|
13
|
+
description: 'Source branch for the action'
|
|
14
|
+
required: false
|
|
15
|
+
branchName:
|
|
16
|
+
description: 'Name for new branch (for create action)'
|
|
17
|
+
required: false
|
|
18
|
+
|
|
19
|
+
outputs:
|
|
20
|
+
success:
|
|
21
|
+
description: 'Whether the action was successful'
|
|
22
|
+
value: ${{ steps.branch-action.outputs.success }}
|
|
23
|
+
message:
|
|
24
|
+
description: 'Result message'
|
|
25
|
+
value: ${{ steps.branch-action.outputs.message }}
|
|
26
|
+
|
|
27
|
+
runs:
|
|
28
|
+
using: 'composite'
|
|
29
|
+
steps:
|
|
30
|
+
- name: Checkout Code
|
|
31
|
+
uses: actions/checkout@v4
|
|
32
|
+
with:
|
|
33
|
+
fetch-depth: 0
|
|
34
|
+
token: ${{ inputs.token }}
|
|
35
|
+
|
|
36
|
+
- name: Validate Inputs
|
|
37
|
+
id: validate
|
|
38
|
+
shell: bash
|
|
39
|
+
run: |
|
|
40
|
+
ACTION="${{ inputs.action }}"
|
|
41
|
+
TARGET="${{ inputs.targetBranch }}"
|
|
42
|
+
SOURCE="${{ inputs.sourceBranch }}"
|
|
43
|
+
BRANCH_NAME="${{ inputs.branchName }}"
|
|
44
|
+
|
|
45
|
+
case "$ACTION" in
|
|
46
|
+
"fast-forward")
|
|
47
|
+
if [ -z "$SOURCE" ]; then
|
|
48
|
+
echo "❌ Source branch is required for fast-forward"
|
|
49
|
+
exit 1
|
|
50
|
+
fi
|
|
51
|
+
;;
|
|
52
|
+
"create")
|
|
53
|
+
if [ -z "$BRANCH_NAME" ]; then
|
|
54
|
+
echo "❌ Branch name is required for create action"
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
57
|
+
;;
|
|
58
|
+
"delete")
|
|
59
|
+
if [ -z "$TARGET" ]; then
|
|
60
|
+
echo "❌ Target branch is required for delete action"
|
|
61
|
+
exit 1
|
|
62
|
+
fi
|
|
63
|
+
;;
|
|
64
|
+
*)
|
|
65
|
+
echo "❌ Invalid action: $ACTION. Must be fast-forward, create, or delete"
|
|
66
|
+
exit 1
|
|
67
|
+
;;
|
|
68
|
+
esac
|
|
69
|
+
|
|
70
|
+
echo "✅ Input validation passed"
|
|
71
|
+
|
|
72
|
+
- name: Perform Branch Action
|
|
73
|
+
id: branch-action
|
|
74
|
+
shell: bash
|
|
75
|
+
run: |
|
|
76
|
+
ACTION="${{ inputs.action }}"
|
|
77
|
+
TARGET="${{ inputs.targetBranch }}"
|
|
78
|
+
SOURCE="${{ inputs.sourceBranch }}"
|
|
79
|
+
BRANCH_NAME="${{ inputs.branchName }}"
|
|
80
|
+
|
|
81
|
+
case "$ACTION" in
|
|
82
|
+
"fast-forward")
|
|
83
|
+
echo "🔄 Fast-forwarding $TARGET to $SOURCE"
|
|
84
|
+
git checkout "$TARGET"
|
|
85
|
+
git merge --ff-only "$SOURCE"
|
|
86
|
+
git push origin "$TARGET"
|
|
87
|
+
echo "success=true" >> $GITHUB_OUTPUT
|
|
88
|
+
echo "message=Successfully fast-forwarded $TARGET to $SOURCE" >> $GITHUB_OUTPUT
|
|
89
|
+
;;
|
|
90
|
+
"create")
|
|
91
|
+
echo "🌱 Creating branch $BRANCH_NAME from $TARGET"
|
|
92
|
+
git checkout "$TARGET"
|
|
93
|
+
git checkout -b "$BRANCH_NAME"
|
|
94
|
+
git push -u origin "$BRANCH_NAME"
|
|
95
|
+
echo "success=true" >> $GITHUB_OUTPUT
|
|
96
|
+
echo "message=Successfully created branch $BRANCH_NAME" >> $GITHUB_OUTPUT
|
|
97
|
+
;;
|
|
98
|
+
"delete")
|
|
99
|
+
echo "🗑️ Deleting branch $TARGET"
|
|
100
|
+
git push origin --delete "$TARGET"
|
|
101
|
+
echo "success=true" >> $GITHUB_OUTPUT
|
|
102
|
+
echo "message=Successfully deleted branch $TARGET" >> $GITHUB_OUTPUT
|
|
103
|
+
;;
|
|
104
|
+
esac
|
|
105
|
+
|
|
106
|
+
- name: Action Summary
|
|
107
|
+
shell: bash
|
|
108
|
+
run: |
|
|
109
|
+
if [ "${{ steps.branch-action.outputs.success }}" == "true" ]; then
|
|
110
|
+
echo "✅ ${{ steps.branch-action.outputs.message }}"
|
|
111
|
+
else
|
|
112
|
+
echo "❌ ${{ steps.branch-action.outputs.message }}"
|
|
113
|
+
fi
|