Skip to content

Commit c79c77d

Browse files
authored
Merge pull request #21 from link-foundation/issue-20-d21ab54e8ff1
Align CI/CD pipelines with template best practices
2 parents fb6e4de + bb3ab1b commit c79c77d

13 files changed

+1639
-70
lines changed

.github/workflows/js.yml

Lines changed: 87 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,62 @@ on:
3535
required: false
3636
type: string
3737

38-
concurrency: ${{ github.workflow }}-${{ github.ref }}
38+
concurrency:
39+
group: ${{ github.workflow }}-${{ github.ref }}
40+
cancel-in-progress: true
3941

4042
jobs:
41-
# Changeset check - only runs on PRs
43+
# === DETECT CHANGES - determines which jobs should run ===
44+
detect-changes:
45+
name: Detect Changes
46+
runs-on: ubuntu-latest
47+
if: github.event_name != 'workflow_dispatch'
48+
outputs:
49+
mjs-changed: ${{ steps.changes.outputs.mjs-changed }}
50+
js-changed: ${{ steps.changes.outputs.js-changed }}
51+
package-changed: ${{ steps.changes.outputs.package-changed }}
52+
docs-changed: ${{ steps.changes.outputs.docs-changed }}
53+
workflow-changed: ${{ steps.changes.outputs.workflow-changed }}
54+
any-code-changed: ${{ steps.changes.outputs.any-code-changed }}
55+
steps:
56+
- uses: actions/checkout@v4
57+
with:
58+
fetch-depth: 0
59+
60+
- name: Detect changes
61+
id: changes
62+
working-directory: ./js
63+
env:
64+
GITHUB_EVENT_NAME: ${{ github.event_name }}
65+
GITHUB_BASE_SHA: ${{ github.event.pull_request.base.sha }}
66+
GITHUB_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
67+
run: node scripts/detect-code-changes.mjs
68+
69+
# === VERSION CHANGE CHECK ===
70+
# Prohibit manual version changes in package.json - versions should only be changed by CI/CD
71+
version-check:
72+
name: Check for Manual Version Changes
73+
runs-on: ubuntu-latest
74+
if: github.event_name == 'pull_request'
75+
steps:
76+
- uses: actions/checkout@v4
77+
with:
78+
fetch-depth: 0
79+
80+
- name: Check for version changes in package.json
81+
working-directory: ./js
82+
env:
83+
GITHUB_HEAD_REF: ${{ github.head_ref }}
84+
GITHUB_BASE_REF: ${{ github.base_ref }}
85+
run: node scripts/check-version.mjs
86+
87+
# === CHANGESET CHECK - only runs on PRs with code changes ===
88+
# Docs-only PRs (./docs folder, markdown files) don't require changesets
4289
changeset-check:
4390
name: Check for Changesets
4491
runs-on: ubuntu-latest
45-
if: github.event_name == 'pull_request'
92+
needs: [detect-changes]
93+
if: github.event_name == 'pull_request' && needs.detect-changes.outputs.any-code-changed == 'true'
4694
steps:
4795
- uses: actions/checkout@v4
4896
with:
@@ -59,6 +107,10 @@ jobs:
59107

60108
- name: Check for changesets
61109
working-directory: ./js
110+
env:
111+
GITHUB_BASE_REF: ${{ github.base_ref }}
112+
GITHUB_BASE_SHA: ${{ github.event.pull_request.base.sha }}
113+
GITHUB_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
62114
run: |
63115
# Skip changeset check for automated version PRs
64116
if [[ "${{ github.head_ref }}" == "changeset-release/"* ]]; then
@@ -69,12 +121,22 @@ jobs:
69121
# Run changeset validation script
70122
node scripts/validate-changeset.mjs
71123
72-
# Linting and formatting - runs after changeset check on PRs, immediately on main
124+
# === LINT AND FORMAT CHECK ===
125+
# Lint runs independently of changeset-check - it's a fast check that should always run
73126
lint:
74127
name: Lint and Format Check
75128
runs-on: ubuntu-latest
76-
needs: [changeset-check]
77-
if: always() && (github.event_name == 'push' || needs.changeset-check.result == 'success')
129+
needs: [detect-changes]
130+
if: |
131+
always() && !cancelled() && (
132+
github.event_name == 'push' ||
133+
github.event_name == 'workflow_dispatch' ||
134+
needs.detect-changes.outputs.mjs-changed == 'true' ||
135+
needs.detect-changes.outputs.js-changed == 'true' ||
136+
needs.detect-changes.outputs.docs-changed == 'true' ||
137+
needs.detect-changes.outputs.package-changed == 'true' ||
138+
needs.detect-changes.outputs.workflow-changed == 'true'
139+
)
78140
steps:
79141
- uses: actions/checkout@v4
80142

@@ -103,8 +165,9 @@ jobs:
103165
test:
104166
name: Test (Node.js on ${{ matrix.os }})
105167
runs-on: ${{ matrix.os }}
106-
needs: [changeset-check]
107-
if: always() && (github.event_name == 'push' || needs.changeset-check.result == 'success')
168+
needs: [detect-changes, changeset-check]
169+
# Run if: push event, OR changeset-check succeeded, OR changeset-check was skipped (docs-only PR)
170+
if: always() && !cancelled() && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || needs.changeset-check.result == 'success' || needs.changeset-check.result == 'skipped')
108171
strategy:
109172
fail-fast: false
110173
matrix:
@@ -135,7 +198,7 @@ jobs:
135198
needs: [lint, test]
136199
# Use always() to ensure this job runs even if changeset-check was skipped
137200
# This is needed because lint/test jobs have a transitive dependency on changeset-check
138-
if: always() && github.ref == 'refs/heads/main' && github.event_name == 'push' && needs.lint.result == 'success' && needs.test.result == 'success'
201+
if: always() && !cancelled() && github.ref == 'refs/heads/main' && github.event_name == 'push' && needs.lint.result == 'success' && needs.test.result == 'success'
139202
runs-on: ubuntu-latest
140203
# Permissions required for npm OIDC trusted publishing
141204
permissions:
@@ -164,11 +227,14 @@ jobs:
164227
- name: Check for changesets
165228
id: check_changesets
166229
working-directory: ./js
230+
run: node scripts/check-changesets.mjs
231+
232+
- name: Merge multiple changesets
233+
if: steps.check_changesets.outputs.has_changesets == 'true' && steps.check_changesets.outputs.changeset_count > 1
234+
working-directory: ./js
167235
run: |
168-
# Count changeset files (excluding README.md and config.json)
169-
CHANGESET_COUNT=$(find .changeset -name "*.md" ! -name "README.md" | wc -l)
170-
echo "Found $CHANGESET_COUNT changeset file(s)"
171-
echo "has_changesets=$([[ $CHANGESET_COUNT -gt 0 ]] && echo 'true' || echo 'false')" >> $GITHUB_OUTPUT
236+
echo "Multiple changesets detected, merging..."
237+
node scripts/merge-changesets.mjs
172238
173239
- name: Version packages and commit to main
174240
if: steps.check_changesets.outputs.has_changesets == 'true'
@@ -200,7 +266,14 @@ jobs:
200266
# Manual Instant Release - triggered via workflow_dispatch with instant mode
201267
instant-release:
202268
name: Instant Release
203-
if: github.event_name == 'workflow_dispatch' && github.event.inputs.release_mode == 'instant'
269+
needs: [lint, test]
270+
# Note: always() is required to evaluate the condition when dependencies use always()
271+
if: |
272+
always() && !cancelled() &&
273+
github.event_name == 'workflow_dispatch' &&
274+
github.event.inputs.release_mode == 'instant' &&
275+
needs.lint.result == 'success' &&
276+
needs.test.result == 'success'
204277
runs-on: ubuntu-latest
205278
# Permissions required for npm OIDC trusted publishing
206279
permissions:

0 commit comments

Comments
 (0)