@panoptic-it-solutions/coolify-setup 1.1.38 → 1.1.40
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/dist/generator.js +4 -4
- package/dist/templates/index.d.ts +1 -1
- package/dist/templates/index.js +1 -1
- package/dist/templates/production-workflow.d.ts +1 -0
- package/dist/templates/production-workflow.js +49 -0
- package/dist/templates/workflow.js +186 -24
- package/package.json +1 -1
- package/dist/templates/staging-workflow.d.ts +0 -1
- package/dist/templates/staging-workflow.js +0 -210
package/dist/generator.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, writeFileSync, readFileSync, unlinkSync, readdirSync, rmSync } from 'fs';
|
|
2
2
|
import { join, dirname } from 'path';
|
|
3
3
|
import { execSync } from 'child_process';
|
|
4
|
-
import { generateDockerfile, generateDockerCompose, generateDockerComposeBuild, generateWorkflow,
|
|
4
|
+
import { generateDockerfile, generateDockerCompose, generateDockerComposeBuild, generateWorkflow, generateProductionWorkflow, generateEntrypoint, generateMigrateScript, generateClaudeRules, } from './templates/index.js';
|
|
5
5
|
function ensureDir(filePath) {
|
|
6
6
|
const dir = dirname(filePath);
|
|
7
7
|
if (!existsSync(dir)) {
|
|
@@ -219,9 +219,9 @@ export async function generateFiles(options) {
|
|
|
219
219
|
packageManager,
|
|
220
220
|
});
|
|
221
221
|
writeFile('.github/workflows/build-deploy.yml', workflow);
|
|
222
|
-
// Generate
|
|
223
|
-
const
|
|
224
|
-
writeFile('.github/workflows/
|
|
222
|
+
// Generate production deploy workflow
|
|
223
|
+
const productionWorkflow = generateProductionWorkflow();
|
|
224
|
+
writeFile('.github/workflows/production-deploy.yml', productionWorkflow);
|
|
225
225
|
// Generate entrypoint.sh
|
|
226
226
|
const entrypoint = generateEntrypoint({
|
|
227
227
|
projectType,
|
|
@@ -2,7 +2,7 @@ export { generateDockerfile, type DockerfileOptions } from './dockerfile.js';
|
|
|
2
2
|
export { generateDockerCompose, type DockerComposeOptions } from './docker-compose.js';
|
|
3
3
|
export { generateDockerComposeBuild, type DockerComposeBuildOptions } from './docker-compose-build.js';
|
|
4
4
|
export { generateWorkflow, type WorkflowOptions } from './workflow.js';
|
|
5
|
-
export {
|
|
5
|
+
export { generateProductionWorkflow } from './production-workflow.js';
|
|
6
6
|
export { generateEntrypoint, type EntrypointOptions } from './entrypoint.js';
|
|
7
7
|
export { generateMigrateScript, type MigrateScriptOptions } from './migrate.js';
|
|
8
8
|
export { generateClaudeRules } from './claude-rules.js';
|
package/dist/templates/index.js
CHANGED
|
@@ -2,7 +2,7 @@ export { generateDockerfile } from './dockerfile.js';
|
|
|
2
2
|
export { generateDockerCompose } from './docker-compose.js';
|
|
3
3
|
export { generateDockerComposeBuild } from './docker-compose-build.js';
|
|
4
4
|
export { generateWorkflow } from './workflow.js';
|
|
5
|
-
export {
|
|
5
|
+
export { generateProductionWorkflow } from './production-workflow.js';
|
|
6
6
|
export { generateEntrypoint } from './entrypoint.js';
|
|
7
7
|
export { generateMigrateScript } from './migrate.js';
|
|
8
8
|
export { generateClaudeRules } from './claude-rules.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function generateProductionWorkflow(): string;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export function generateProductionWorkflow() {
|
|
2
|
+
return `name: Production Deploy
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
tag-production:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Get version from package.json
|
|
20
|
+
id: version
|
|
21
|
+
run: |
|
|
22
|
+
VERSION=\$(node -p "require('./package.json').version")
|
|
23
|
+
echo "version=\$VERSION" >> \$GITHUB_OUTPUT
|
|
24
|
+
|
|
25
|
+
- name: Create production tag
|
|
26
|
+
run: |
|
|
27
|
+
TAG_NAME="v\${{ steps.version.outputs.version }}"
|
|
28
|
+
|
|
29
|
+
# Check if tag already exists
|
|
30
|
+
if git rev-parse "\$TAG_NAME" >/dev/null 2>&1; then
|
|
31
|
+
echo "Tag \$TAG_NAME already exists, skipping"
|
|
32
|
+
else
|
|
33
|
+
git config user.name "github-actions[bot]"
|
|
34
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
35
|
+
git tag "\$TAG_NAME"
|
|
36
|
+
git push origin "\$TAG_NAME"
|
|
37
|
+
echo "Created production tag \$TAG_NAME"
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
- name: Output deployment info
|
|
41
|
+
run: |
|
|
42
|
+
echo "## Production Deployment" >> \$GITHUB_STEP_SUMMARY
|
|
43
|
+
echo "" >> \$GITHUB_STEP_SUMMARY
|
|
44
|
+
echo "**Version:** v\${{ steps.version.outputs.version }}" >> \$GITHUB_STEP_SUMMARY
|
|
45
|
+
echo "**Tag:** v\${{ steps.version.outputs.version }}" >> \$GITHUB_STEP_SUMMARY
|
|
46
|
+
echo "" >> \$GITHUB_STEP_SUMMARY
|
|
47
|
+
echo "Coolify will auto-deploy when it detects this commit on main." >> \$GITHUB_STEP_SUMMARY
|
|
48
|
+
`;
|
|
49
|
+
}
|
|
@@ -26,25 +26,39 @@ ${pnpmSetup}
|
|
|
26
26
|
|
|
27
27
|
- name: Check migrations are up to date
|
|
28
28
|
run: |
|
|
29
|
+
# Check if migrations folder exists and has files
|
|
30
|
+
if [ ! -d "${dbPath}/migrations" ] || [ -z "$(ls -A ${dbPath}/migrations 2>/dev/null)" ]; then
|
|
31
|
+
echo "::error::Migrations folder missing or empty!"
|
|
32
|
+
echo "Run locally: ${drizzleCmd}"
|
|
33
|
+
echo "Then commit the generated migration files."
|
|
34
|
+
exit 1
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# Run generate and check if it creates NEW migration files
|
|
38
|
+
# (this catches schema changes that weren't migrated)
|
|
39
|
+
BEFORE_COUNT=$(find ${dbPath}/migrations -name "*.sql" 2>/dev/null | wc -l)
|
|
29
40
|
${drizzleCmd}
|
|
30
|
-
|
|
41
|
+
AFTER_COUNT=$(find ${dbPath}/migrations -name "*.sql" 2>/dev/null | wc -l)
|
|
42
|
+
|
|
43
|
+
if [ "$AFTER_COUNT" -gt "$BEFORE_COUNT" ]; then
|
|
31
44
|
echo "::error::Schema changes detected without migrations!"
|
|
32
|
-
echo "
|
|
45
|
+
echo "drizzle-kit generate created new migration files."
|
|
33
46
|
echo ""
|
|
34
47
|
echo "To fix this, run locally:"
|
|
35
48
|
echo " ${drizzleCmd}"
|
|
36
49
|
echo ""
|
|
37
50
|
echo "Then commit the generated migration files."
|
|
38
51
|
git status ${dbPath}/migrations
|
|
39
|
-
git diff ${dbPath}/migrations
|
|
40
52
|
exit 1
|
|
41
53
|
fi
|
|
54
|
+
|
|
42
55
|
echo "Migrations are up to date"
|
|
43
56
|
|
|
44
57
|
- name: Verify migrations exist
|
|
45
58
|
run: |
|
|
46
59
|
echo "Checking migrations in build context:"
|
|
47
60
|
ls -la ${dbPath}/migrations/
|
|
61
|
+
test -f ${dbPath}/migrations/meta/_journal.json || (echo "ERROR: _journal.json missing!" && exit 1)
|
|
48
62
|
` : '';
|
|
49
63
|
return `name: Build and Deploy
|
|
50
64
|
|
|
@@ -62,7 +76,7 @@ env:
|
|
|
62
76
|
PROJECT_NAME: ${projectName}
|
|
63
77
|
|
|
64
78
|
jobs:
|
|
65
|
-
build-and-
|
|
79
|
+
build-and-deploy:
|
|
66
80
|
runs-on: self-hosted
|
|
67
81
|
permissions:
|
|
68
82
|
contents: write
|
|
@@ -71,37 +85,162 @@ jobs:
|
|
|
71
85
|
steps:
|
|
72
86
|
- name: Checkout
|
|
73
87
|
uses: actions/checkout@v4
|
|
88
|
+
with:
|
|
89
|
+
fetch-depth: 0
|
|
74
90
|
${migrationCheck}
|
|
91
|
+
- name: Configure Git (staging only)
|
|
92
|
+
if: github.ref_name == 'staging'
|
|
93
|
+
run: |
|
|
94
|
+
git config user.name "github-actions[bot]"
|
|
95
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
96
|
+
|
|
97
|
+
- name: Get last staging tag
|
|
98
|
+
if: github.ref_name == 'staging'
|
|
99
|
+
id: last_tag
|
|
100
|
+
run: |
|
|
101
|
+
LAST_TAG=\$(git tag -l "staging-v*" --sort=-v:refname | head -n1)
|
|
102
|
+
if [ -z "\$LAST_TAG" ]; then
|
|
103
|
+
LAST_TAG=\$(git rev-list --max-parents=0 HEAD)
|
|
104
|
+
fi
|
|
105
|
+
echo "tag=\$LAST_TAG" >> \$GITHUB_OUTPUT
|
|
106
|
+
|
|
107
|
+
- name: Determine version bump from commits
|
|
108
|
+
if: github.ref_name == 'staging'
|
|
109
|
+
id: bump
|
|
110
|
+
run: |
|
|
111
|
+
COMMITS=\$(git log \${{ steps.last_tag.outputs.tag }}..HEAD --pretty=format:"%s" 2>/dev/null || git log --pretty=format:"%s")
|
|
112
|
+
|
|
113
|
+
BUMP="patch"
|
|
114
|
+
|
|
115
|
+
if echo "\$COMMITS" | grep -qiE "^feat(\\(.+\\))?!:|BREAKING CHANGE:"; then
|
|
116
|
+
BUMP="major"
|
|
117
|
+
elif echo "\$COMMITS" | grep -qiE "^feat(\\(.+\\))?:"; then
|
|
118
|
+
BUMP="minor"
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
echo "type=\$BUMP" >> \$GITHUB_OUTPUT
|
|
122
|
+
|
|
123
|
+
- name: Bump version
|
|
124
|
+
if: github.ref_name == 'staging'
|
|
125
|
+
id: version
|
|
126
|
+
run: |
|
|
127
|
+
CURRENT=\$(node -p "require('./package.json').version")
|
|
128
|
+
LAST_TAG="\${{ steps.last_tag.outputs.tag }}"
|
|
129
|
+
|
|
130
|
+
# Check if HEAD is the same as the last tag (rerun scenario with no new commits)
|
|
131
|
+
LAST_TAG_SHA=\$(git rev-parse "\$LAST_TAG" 2>/dev/null || echo "")
|
|
132
|
+
HEAD_SHA=\$(git rev-parse HEAD)
|
|
133
|
+
|
|
134
|
+
if [ "\$LAST_TAG_SHA" = "\$HEAD_SHA" ]; then
|
|
135
|
+
echo "HEAD is at \$LAST_TAG, no new commits to version"
|
|
136
|
+
echo "version=\$CURRENT" >> \$GITHUB_OUTPUT
|
|
137
|
+
echo "skip_bump=true" >> \$GITHUB_OUTPUT
|
|
138
|
+
exit 0
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
# Check if there are any commits since last tag (excluding version bump commits)
|
|
142
|
+
NEW_COMMITS=\$(git log "\$LAST_TAG"..HEAD --pretty=format:"%s" --invert-grep --grep="^chore(release):" 2>/dev/null | head -1)
|
|
143
|
+
if [ -z "\$NEW_COMMITS" ]; then
|
|
144
|
+
echo "No new commits since \$LAST_TAG (only release commits)"
|
|
145
|
+
echo "version=\$CURRENT" >> \$GITHUB_OUTPUT
|
|
146
|
+
echo "skip_bump=true" >> \$GITHUB_OUTPUT
|
|
147
|
+
exit 0
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
IFS='.' read -r MAJOR MINOR PATCH <<< "\$CURRENT"
|
|
151
|
+
|
|
152
|
+
case "\${{ steps.bump.outputs.type }}" in
|
|
153
|
+
major)
|
|
154
|
+
MAJOR=\$((MAJOR + 1))
|
|
155
|
+
MINOR=0
|
|
156
|
+
PATCH=0
|
|
157
|
+
;;
|
|
158
|
+
minor)
|
|
159
|
+
MINOR=\$((MINOR + 1))
|
|
160
|
+
PATCH=0
|
|
161
|
+
;;
|
|
162
|
+
patch)
|
|
163
|
+
PATCH=\$((PATCH + 1))
|
|
164
|
+
;;
|
|
165
|
+
esac
|
|
166
|
+
|
|
167
|
+
NEW_VERSION="\${MAJOR}.\${MINOR}.\${PATCH}"
|
|
168
|
+
npm version \$NEW_VERSION --no-git-tag-version
|
|
169
|
+
|
|
170
|
+
echo "version=\$NEW_VERSION" >> \$GITHUB_OUTPUT
|
|
171
|
+
echo "skip_bump=false" >> \$GITHUB_OUTPUT
|
|
172
|
+
|
|
173
|
+
- name: Commit version bump
|
|
174
|
+
if: github.ref_name == 'staging' && steps.version.outputs.skip_bump != 'true'
|
|
175
|
+
run: |
|
|
176
|
+
git add package.json
|
|
177
|
+
git commit -m "chore(release): v\${{ steps.version.outputs.version }}"
|
|
178
|
+
|
|
179
|
+
- name: Create and push staging tag
|
|
180
|
+
if: github.ref_name == 'staging' && steps.version.outputs.skip_bump != 'true'
|
|
181
|
+
run: |
|
|
182
|
+
TAG_NAME="staging-v\${{ steps.version.outputs.version }}"
|
|
183
|
+
# Check if tag already exists
|
|
184
|
+
if git rev-parse "\$TAG_NAME" >/dev/null 2>&1; then
|
|
185
|
+
EXISTING_SHA=\$(git rev-parse "\$TAG_NAME")
|
|
186
|
+
CURRENT_SHA=\$(git rev-parse HEAD)
|
|
187
|
+
if [ "\$EXISTING_SHA" = "\$CURRENT_SHA" ]; then
|
|
188
|
+
echo "Tag \$TAG_NAME already exists at current commit, skipping"
|
|
189
|
+
else
|
|
190
|
+
echo "Error: Tag \$TAG_NAME exists at different commit"
|
|
191
|
+
exit 1
|
|
192
|
+
fi
|
|
193
|
+
else
|
|
194
|
+
git tag "\$TAG_NAME"
|
|
195
|
+
fi
|
|
196
|
+
git push origin staging --tags
|
|
197
|
+
|
|
75
198
|
- name: Get commit SHA
|
|
76
199
|
id: sha
|
|
77
|
-
run: echo "sha=\$(git rev-parse --short HEAD)" >>
|
|
200
|
+
run: echo "sha=\$(git rev-parse --short HEAD)" >> \$GITHUB_OUTPUT
|
|
78
201
|
|
|
79
|
-
- name: Build
|
|
202
|
+
- name: Build Docker image
|
|
80
203
|
run: |
|
|
81
204
|
export COMMIT_SHA=\${{ steps.sha.outputs.sha }}
|
|
82
205
|
export COMPOSE_PROJECT_NAME=\${{ env.PROJECT_NAME }}
|
|
83
|
-
|
|
84
206
|
docker compose -f docker-compose.build.yml build --no-cache
|
|
207
|
+
|
|
208
|
+
- name: Push to registry (staging only)
|
|
209
|
+
if: github.ref_name == 'staging'
|
|
210
|
+
run: |
|
|
211
|
+
export COMMIT_SHA=\${{ steps.sha.outputs.sha }}
|
|
212
|
+
export COMPOSE_PROJECT_NAME=\${{ env.PROJECT_NAME }}
|
|
85
213
|
docker compose -f docker-compose.build.yml push
|
|
86
214
|
|
|
87
215
|
# Also tag and push as latest
|
|
88
216
|
docker tag \${{ env.REGISTRY }}/\${{ env.PROJECT_NAME }}-app:\${{ steps.sha.outputs.sha }} \${{ env.REGISTRY }}/\${{ env.PROJECT_NAME }}-app:latest
|
|
89
217
|
docker push \${{ env.REGISTRY }}/\${{ env.PROJECT_NAME }}-app:latest
|
|
90
218
|
|
|
219
|
+
- name: Output version info (staging only)
|
|
220
|
+
if: github.ref_name == 'staging'
|
|
221
|
+
run: |
|
|
222
|
+
echo "## Version Summary" >> \$GITHUB_STEP_SUMMARY
|
|
223
|
+
echo "" >> \$GITHUB_STEP_SUMMARY
|
|
224
|
+
echo "**Version:** v\${{ steps.version.outputs.version }}" >> \$GITHUB_STEP_SUMMARY
|
|
225
|
+
echo "**Bump Type:** \${{ steps.bump.outputs.type }}" >> \$GITHUB_STEP_SUMMARY
|
|
226
|
+
echo "**Skipped:** \${{ steps.version.outputs.skip_bump }}" >> \$GITHUB_STEP_SUMMARY
|
|
227
|
+
|
|
91
228
|
- name: Determine target branch
|
|
92
229
|
id: target
|
|
93
230
|
run: |
|
|
94
231
|
SOURCE_BRANCH="\${{ github.ref_name }}"
|
|
95
232
|
|
|
96
233
|
# Feature/fix/hotfix branches target develop
|
|
97
|
-
if [[ "
|
|
98
|
-
echo "branch=develop" >>
|
|
234
|
+
if [[ "\$SOURCE_BRANCH" == feature/* ]] || [[ "\$SOURCE_BRANCH" == fix/* ]] || [[ "\$SOURCE_BRANCH" == hotfix/* ]]; then
|
|
235
|
+
echo "branch=develop" >> \$GITHUB_OUTPUT
|
|
99
236
|
# Develop targets staging
|
|
100
|
-
elif [[ "
|
|
101
|
-
echo "branch=staging" >>
|
|
102
|
-
# Staging
|
|
237
|
+
elif [[ "\$SOURCE_BRANCH" == "develop" ]]; then
|
|
238
|
+
echo "branch=staging" >> \$GITHUB_OUTPUT
|
|
239
|
+
# Staging targets main
|
|
240
|
+
elif [[ "\$SOURCE_BRANCH" == "staging" ]]; then
|
|
241
|
+
echo "branch=main" >> \$GITHUB_OUTPUT
|
|
103
242
|
else
|
|
104
|
-
echo "branch=" >>
|
|
243
|
+
echo "branch=" >> \$GITHUB_OUTPUT
|
|
105
244
|
fi
|
|
106
245
|
|
|
107
246
|
- name: Create deploy PR
|
|
@@ -131,7 +270,7 @@ ${migrationCheck}
|
|
|
131
270
|
owner: context.repo.owner,
|
|
132
271
|
repo: context.repo.repo,
|
|
133
272
|
title: \`Deploy: \${sourceBranch} -> \${targetBranch}\`,
|
|
134
|
-
body: \`Automated deployment PR from \${sourceBranch} to \${targetBranch}.\\n\\n**Commit:** \${{ steps.sha.outputs.sha }}\\n**Image:** \${{ env.REGISTRY }}
|
|
273
|
+
body: \`Automated deployment PR from \${sourceBranch} to \${targetBranch}.\\n\\n**Commit:** \${{ steps.sha.outputs.sha }}\\n**Image:** \${{ env.REGISTRY }}/${projectName}-app:\${{ steps.sha.outputs.sha }}\\n\\nMerge this PR to trigger deployment.\`,
|
|
135
274
|
head: sourceBranch,
|
|
136
275
|
base: targetBranch
|
|
137
276
|
});
|
|
@@ -140,22 +279,22 @@ ${migrationCheck}
|
|
|
140
279
|
console.log(\`PR creation skipped: \${error.message}\`);
|
|
141
280
|
}
|
|
142
281
|
|
|
143
|
-
- name: Create
|
|
144
|
-
if: github.
|
|
282
|
+
- name: Create sync PR to develop (staging only)
|
|
283
|
+
if: github.ref_name == 'staging' && steps.version.outputs.skip_bump != 'true'
|
|
145
284
|
uses: actions/github-script@v7
|
|
146
285
|
with:
|
|
147
286
|
script: |
|
|
148
|
-
// Check if PR already exists
|
|
287
|
+
// Check if sync PR already exists
|
|
149
288
|
const { data: prs } = await github.rest.pulls.list({
|
|
150
289
|
owner: context.repo.owner,
|
|
151
290
|
repo: context.repo.repo,
|
|
152
291
|
head: \`\${context.repo.owner}:staging\`,
|
|
153
|
-
base: '
|
|
292
|
+
base: 'develop',
|
|
154
293
|
state: 'open'
|
|
155
294
|
});
|
|
156
295
|
|
|
157
296
|
if (prs.length > 0) {
|
|
158
|
-
console.log(\`PR #\${prs[0].number} already exists for staging ->
|
|
297
|
+
console.log(\`Sync PR #\${prs[0].number} already exists for staging -> develop\`);
|
|
159
298
|
return;
|
|
160
299
|
}
|
|
161
300
|
|
|
@@ -163,14 +302,37 @@ ${migrationCheck}
|
|
|
163
302
|
const { data: pr } = await github.rest.pulls.create({
|
|
164
303
|
owner: context.repo.owner,
|
|
165
304
|
repo: context.repo.repo,
|
|
166
|
-
title:
|
|
167
|
-
body: \`
|
|
305
|
+
title: \`Sync: version bump v\${{ steps.version.outputs.version }} → develop\`,
|
|
306
|
+
body: \`Syncs the version bump commit back to develop to prevent package.json conflicts in future merges.\\n\\n**Version:** v\${{ steps.version.outputs.version }}\\n\\nMerge this PR to keep branches in sync.\`,
|
|
168
307
|
head: 'staging',
|
|
169
|
-
base: '
|
|
308
|
+
base: 'develop'
|
|
170
309
|
});
|
|
171
|
-
console.log(\`Created PR #\${pr.number}\`);
|
|
310
|
+
console.log(\`Created sync PR #\${pr.number}\`);
|
|
311
|
+
|
|
312
|
+
// Enable auto-merge for sync PR (just version bump)
|
|
313
|
+
try {
|
|
314
|
+
await github.graphql(\`
|
|
315
|
+
mutation(\$pullRequestId: ID!) {
|
|
316
|
+
enablePullRequestAutoMerge(input: {
|
|
317
|
+
pullRequestId: \$pullRequestId,
|
|
318
|
+
mergeMethod: MERGE
|
|
319
|
+
}) {
|
|
320
|
+
pullRequest {
|
|
321
|
+
autoMergeRequest {
|
|
322
|
+
enabledAt
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
\`, {
|
|
328
|
+
pullRequestId: pr.node_id
|
|
329
|
+
});
|
|
330
|
+
console.log(\`Enabled auto-merge for sync PR #\${pr.number}\`);
|
|
331
|
+
} catch (autoMergeError) {
|
|
332
|
+
console.log(\`Auto-merge not available: \${autoMergeError.message}\`);
|
|
333
|
+
}
|
|
172
334
|
} catch (error) {
|
|
173
|
-
console.log(\`PR creation skipped: \${error.message}\`);
|
|
335
|
+
console.log(\`Sync PR creation skipped: \${error.message}\`);
|
|
174
336
|
}
|
|
175
337
|
`;
|
|
176
338
|
}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function generateStagingWorkflow(): string;
|
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
export function generateStagingWorkflow() {
|
|
2
|
-
return `name: Staging Version
|
|
3
|
-
|
|
4
|
-
on:
|
|
5
|
-
push:
|
|
6
|
-
branches:
|
|
7
|
-
- staging
|
|
8
|
-
|
|
9
|
-
permissions:
|
|
10
|
-
contents: write
|
|
11
|
-
pull-requests: write
|
|
12
|
-
|
|
13
|
-
jobs:
|
|
14
|
-
version:
|
|
15
|
-
runs-on: ubuntu-latest
|
|
16
|
-
steps:
|
|
17
|
-
- name: Checkout
|
|
18
|
-
uses: actions/checkout@v4
|
|
19
|
-
with:
|
|
20
|
-
fetch-depth: 0
|
|
21
|
-
token: \${{ secrets.GITHUB_TOKEN }}
|
|
22
|
-
|
|
23
|
-
- name: Setup Node.js
|
|
24
|
-
uses: actions/setup-node@v4
|
|
25
|
-
with:
|
|
26
|
-
node-version: '22'
|
|
27
|
-
|
|
28
|
-
- name: Configure Git
|
|
29
|
-
run: |
|
|
30
|
-
git config user.name "github-actions[bot]"
|
|
31
|
-
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
32
|
-
|
|
33
|
-
- name: Get last staging tag
|
|
34
|
-
id: last_tag
|
|
35
|
-
run: |
|
|
36
|
-
LAST_TAG=\$(git tag -l "staging-v*" --sort=-v:refname | head -n1)
|
|
37
|
-
if [ -z "\$LAST_TAG" ]; then
|
|
38
|
-
LAST_TAG=\$(git rev-list --max-parents=0 HEAD)
|
|
39
|
-
fi
|
|
40
|
-
echo "tag=\$LAST_TAG" >> \$GITHUB_OUTPUT
|
|
41
|
-
|
|
42
|
-
- name: Determine version bump from commits
|
|
43
|
-
id: bump
|
|
44
|
-
run: |
|
|
45
|
-
COMMITS=\$(git log \${{ steps.last_tag.outputs.tag }}..HEAD --pretty=format:"%s" 2>/dev/null || git log --pretty=format:"%s")
|
|
46
|
-
|
|
47
|
-
BUMP="patch"
|
|
48
|
-
|
|
49
|
-
if echo "\$COMMITS" | grep -qiE "^feat(\\(.+\\))?!:|BREAKING CHANGE:"; then
|
|
50
|
-
BUMP="major"
|
|
51
|
-
elif echo "\$COMMITS" | grep -qiE "^feat(\\(.+\\))?:"; then
|
|
52
|
-
BUMP="minor"
|
|
53
|
-
fi
|
|
54
|
-
|
|
55
|
-
echo "type=\$BUMP" >> \$GITHUB_OUTPUT
|
|
56
|
-
|
|
57
|
-
- name: Bump version
|
|
58
|
-
id: version
|
|
59
|
-
run: |
|
|
60
|
-
CURRENT=\$(node -p "require('./package.json').version")
|
|
61
|
-
LAST_TAG="\${{ steps.last_tag.outputs.tag }}"
|
|
62
|
-
|
|
63
|
-
# Check if HEAD is the same as the last tag (rerun scenario with no new commits)
|
|
64
|
-
LAST_TAG_SHA=\$(git rev-parse "\$LAST_TAG" 2>/dev/null || echo "")
|
|
65
|
-
HEAD_SHA=\$(git rev-parse HEAD)
|
|
66
|
-
|
|
67
|
-
if [ "\$LAST_TAG_SHA" = "\$HEAD_SHA" ]; then
|
|
68
|
-
echo "HEAD is at \$LAST_TAG, no new commits to version"
|
|
69
|
-
echo "version=\$CURRENT" >> \$GITHUB_OUTPUT
|
|
70
|
-
echo "skip_commit=true" >> \$GITHUB_OUTPUT
|
|
71
|
-
exit 0
|
|
72
|
-
fi
|
|
73
|
-
|
|
74
|
-
# Check if there are any commits since last tag (excluding version bump commits)
|
|
75
|
-
NEW_COMMITS=\$(git log "\$LAST_TAG"..HEAD --pretty=format:"%s" --invert-grep --grep="^chore(release):" 2>/dev/null | head -1)
|
|
76
|
-
if [ -z "\$NEW_COMMITS" ]; then
|
|
77
|
-
echo "No new commits since \$LAST_TAG (only release commits)"
|
|
78
|
-
echo "version=\$CURRENT" >> \$GITHUB_OUTPUT
|
|
79
|
-
echo "skip_commit=true" >> \$GITHUB_OUTPUT
|
|
80
|
-
exit 0
|
|
81
|
-
fi
|
|
82
|
-
|
|
83
|
-
IFS='.' read -r MAJOR MINOR PATCH <<< "\$CURRENT"
|
|
84
|
-
|
|
85
|
-
case "\${{ steps.bump.outputs.type }}" in
|
|
86
|
-
major)
|
|
87
|
-
MAJOR=\$((MAJOR + 1))
|
|
88
|
-
MINOR=0
|
|
89
|
-
PATCH=0
|
|
90
|
-
;;
|
|
91
|
-
minor)
|
|
92
|
-
MINOR=\$((MINOR + 1))
|
|
93
|
-
PATCH=0
|
|
94
|
-
;;
|
|
95
|
-
patch)
|
|
96
|
-
PATCH=\$((PATCH + 1))
|
|
97
|
-
;;
|
|
98
|
-
esac
|
|
99
|
-
|
|
100
|
-
NEW_VERSION="\${MAJOR}.\${MINOR}.\${PATCH}"
|
|
101
|
-
npm version \$NEW_VERSION --no-git-tag-version
|
|
102
|
-
|
|
103
|
-
echo "version=\$NEW_VERSION" >> \$GITHUB_OUTPUT
|
|
104
|
-
echo "skip_commit=false" >> \$GITHUB_OUTPUT
|
|
105
|
-
|
|
106
|
-
- name: Generate changelog
|
|
107
|
-
id: changelog
|
|
108
|
-
if: steps.version.outputs.skip_commit != 'true'
|
|
109
|
-
run: |
|
|
110
|
-
LAST_TAG="\${{ steps.last_tag.outputs.tag }}"
|
|
111
|
-
|
|
112
|
-
{
|
|
113
|
-
echo "changelog<<EOF"
|
|
114
|
-
echo "## Changes in v\${{ steps.version.outputs.version }}"
|
|
115
|
-
echo ""
|
|
116
|
-
|
|
117
|
-
# Features
|
|
118
|
-
FEATURES=\$(git log \$LAST_TAG..HEAD --pretty=format:"- %s" --grep="^feat" 2>/dev/null || true)
|
|
119
|
-
if [ -n "\$FEATURES" ]; then
|
|
120
|
-
echo "### Features"
|
|
121
|
-
echo "\$FEATURES"
|
|
122
|
-
echo ""
|
|
123
|
-
fi
|
|
124
|
-
|
|
125
|
-
# Fixes
|
|
126
|
-
FIXES=\$(git log \$LAST_TAG..HEAD --pretty=format:"- %s" --grep="^fix" 2>/dev/null || true)
|
|
127
|
-
if [ -n "\$FIXES" ]; then
|
|
128
|
-
echo "### Bug Fixes"
|
|
129
|
-
echo "\$FIXES"
|
|
130
|
-
echo ""
|
|
131
|
-
fi
|
|
132
|
-
|
|
133
|
-
# Other changes
|
|
134
|
-
OTHERS=\$(git log \$LAST_TAG..HEAD --pretty=format:"- %s" --invert-grep --grep="^feat" --grep="^fix" 2>/dev/null | head -20 || true)
|
|
135
|
-
if [ -n "\$OTHERS" ]; then
|
|
136
|
-
echo "### Other Changes"
|
|
137
|
-
echo "\$OTHERS"
|
|
138
|
-
echo ""
|
|
139
|
-
fi
|
|
140
|
-
|
|
141
|
-
echo "EOF"
|
|
142
|
-
} >> \$GITHUB_OUTPUT
|
|
143
|
-
|
|
144
|
-
- name: Commit version bump
|
|
145
|
-
if: steps.version.outputs.skip_commit != 'true'
|
|
146
|
-
run: |
|
|
147
|
-
git add package.json
|
|
148
|
-
git commit -m "chore(release): v\${{ steps.version.outputs.version }}"
|
|
149
|
-
|
|
150
|
-
- name: Create and push tag
|
|
151
|
-
if: steps.version.outputs.skip_commit != 'true'
|
|
152
|
-
run: |
|
|
153
|
-
TAG_NAME="staging-v\${{ steps.version.outputs.version }}"
|
|
154
|
-
# Check if tag already exists
|
|
155
|
-
if git rev-parse "\$TAG_NAME" >/dev/null 2>&1; then
|
|
156
|
-
EXISTING_SHA=\$(git rev-parse "\$TAG_NAME")
|
|
157
|
-
CURRENT_SHA=\$(git rev-parse HEAD)
|
|
158
|
-
if [ "\$EXISTING_SHA" = "\$CURRENT_SHA" ]; then
|
|
159
|
-
echo "Tag \$TAG_NAME already exists at current commit, skipping"
|
|
160
|
-
else
|
|
161
|
-
echo "Error: Tag \$TAG_NAME exists at different commit"
|
|
162
|
-
exit 1
|
|
163
|
-
fi
|
|
164
|
-
else
|
|
165
|
-
git tag "\$TAG_NAME"
|
|
166
|
-
fi
|
|
167
|
-
git push origin staging --tags
|
|
168
|
-
|
|
169
|
-
- name: Output version info
|
|
170
|
-
run: |
|
|
171
|
-
echo "## Version Summary" >> \$GITHUB_STEP_SUMMARY
|
|
172
|
-
echo "" >> \$GITHUB_STEP_SUMMARY
|
|
173
|
-
echo "**Version:** v\${{ steps.version.outputs.version }}" >> \$GITHUB_STEP_SUMMARY
|
|
174
|
-
echo "**Bump Type:** \${{ steps.bump.outputs.type }}" >> \$GITHUB_STEP_SUMMARY
|
|
175
|
-
echo "**Skipped:** \${{ steps.version.outputs.skip_commit }}" >> \$GITHUB_STEP_SUMMARY
|
|
176
|
-
|
|
177
|
-
- name: Create sync PR to develop
|
|
178
|
-
if: steps.version.outputs.skip_commit != 'true'
|
|
179
|
-
uses: actions/github-script@v7
|
|
180
|
-
with:
|
|
181
|
-
script: |
|
|
182
|
-
// Check if sync PR already exists
|
|
183
|
-
const { data: prs } = await github.rest.pulls.list({
|
|
184
|
-
owner: context.repo.owner,
|
|
185
|
-
repo: context.repo.repo,
|
|
186
|
-
head: \`\${context.repo.owner}:staging\`,
|
|
187
|
-
base: 'develop',
|
|
188
|
-
state: 'open'
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
if (prs.length > 0) {
|
|
192
|
-
console.log(\`Sync PR #\${prs[0].number} already exists for staging -> develop\`);
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
try {
|
|
197
|
-
const { data: pr } = await github.rest.pulls.create({
|
|
198
|
-
owner: context.repo.owner,
|
|
199
|
-
repo: context.repo.repo,
|
|
200
|
-
title: \`Sync: version bump v\${{ steps.version.outputs.version }} → develop\`,
|
|
201
|
-
body: \`Syncs the version bump commit back to develop to prevent package.json conflicts in future merges.\\n\\n**Version:** v\${{ steps.version.outputs.version }}\\n\\nMerge this PR to keep branches in sync.\`,
|
|
202
|
-
head: 'staging',
|
|
203
|
-
base: 'develop'
|
|
204
|
-
});
|
|
205
|
-
console.log(\`Created sync PR #\${pr.number}\`);
|
|
206
|
-
} catch (error) {
|
|
207
|
-
console.log(\`Sync PR creation skipped: \${error.message}\`);
|
|
208
|
-
}
|
|
209
|
-
`;
|
|
210
|
-
}
|