@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 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, generateStagingWorkflow, generateEntrypoint, generateMigrateScript, generateClaudeRules, } from './templates/index.js';
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 staging version workflow
223
- const stagingWorkflow = generateStagingWorkflow();
224
- writeFile('.github/workflows/staging-version.yml', stagingWorkflow);
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 { generateStagingWorkflow } from './staging-workflow.js';
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';
@@ -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 { generateStagingWorkflow } from './staging-workflow.js';
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
- if [ -n "$(git status --porcelain ${dbPath}/migrations)" ]; then
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 "The database schema has changed but migrations are not up to date."
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-push:
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)" >> $GITHUB_OUTPUT
200
+ run: echo "sha=\$(git rev-parse --short HEAD)" >> \$GITHUB_OUTPUT
78
201
 
79
- - name: Build and push images
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 [[ "$SOURCE_BRANCH" == feature/* ]] || [[ "$SOURCE_BRANCH" == fix/* ]] || [[ "$SOURCE_BRANCH" == hotfix/* ]]; then
98
- echo "branch=develop" >> $GITHUB_OUTPUT
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 [[ "$SOURCE_BRANCH" == "develop" ]]; then
101
- echo "branch=staging" >> $GITHUB_OUTPUT
102
- # Staging/other branches don't create PRs (staging->main handled separately)
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=" >> $GITHUB_OUTPUT
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 }}/\${{ env.PROJECT_NAME }}-app:\${{ steps.sha.outputs.sha }}\\n\\nMerge this PR to trigger deployment.\`,
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 production PR
144
- if: github.ref == 'refs/heads/staging'
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: 'main',
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 -> main\`);
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: 'Deploy to Production: staging -> main',
167
- body: \`Promote staging to production.\\n\\n**Commit:** \${{ steps.sha.outputs.sha }}\\n**Image:** \${{ env.REGISTRY }}/\${{ env.PROJECT_NAME }}-app:\${{ steps.sha.outputs.sha }}\\n\\nMerge this PR to deploy to production.\`,
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: 'main'
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@panoptic-it-solutions/coolify-setup",
3
- "version": "1.1.38",
3
+ "version": "1.1.40",
4
4
  "description": "CLI tool for setting up Coolify deployment on Panoptic projects",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -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
- }