Skip to content

Commit 39b0e1c

Browse files
committed
feat: implement core publishing logic and version bump workflow
1 parent e4707a5 commit 39b0e1c

File tree

3 files changed

+240
-122
lines changed

3 files changed

+240
-122
lines changed

.github/workflows/publish-core.yml

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
name: Core Publishing Logic
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
version_bump:
7+
description: 'Type of version bump to perform'
8+
required: true
9+
type: string
10+
npm_tag:
11+
description: 'Custom npm dist-tag'
12+
required: false
13+
type: string
14+
default: ''
15+
dry_run:
16+
description: 'Dry run flag'
17+
required: false
18+
type: boolean
19+
default: false
20+
branch_name:
21+
description: 'Branch name'
22+
required: true
23+
type: string
24+
secrets:
25+
NODE_AUTH_TOKEN:
26+
required: true
27+
28+
jobs:
29+
publish:
30+
name: Publish Package
31+
runs-on: ubuntu-24.04
32+
environment: production
33+
34+
steps:
35+
- name: Check out code
36+
uses: actions/checkout@v4
37+
with:
38+
fetch-depth: 2
39+
ref: ${{ inputs.branch_name }}
40+
41+
- name: Setup Node.js
42+
uses: actions/setup-node@v4
43+
with:
44+
node-version-file: .nvmrc
45+
registry-url: https://registry.npmjs.org
46+
scope: '@defra'
47+
48+
- name: Install dependencies
49+
run: npm ci
50+
51+
- name: Prepare version based on branch
52+
id: prepare-version
53+
run: |
54+
# Set the initial bump type from input
55+
BUMP_TYPE="${{ inputs.version_bump }}"
56+
echo "Initial bump type: $BUMP_TYPE"
57+
58+
# For release branches, respect the branch naming convention
59+
if [[ "${{ inputs.branch_name }}" =~ release/v([0-9]+) ]]; then
60+
# Extract major version number
61+
MAJOR_VERSION="${BASH_REMATCH[1]}"
62+
echo "Release branch for major version: $MAJOR_VERSION"
63+
64+
# Check current version
65+
CURRENT_VERSION=$(npm pkg get version | tr -d \")
66+
CURRENT_MAJOR=$(echo $CURRENT_VERSION | cut -d. -f1)
67+
68+
# If the major version doesn't match, reset to major.0.0
69+
if [[ "$CURRENT_MAJOR" != "$MAJOR_VERSION" ]]; then
70+
echo "Resetting version to $MAJOR_VERSION.0.0"
71+
npm version $MAJOR_VERSION.0.0 --git-tag-version false --allow-same-version
72+
73+
# Override to patch since we've already set the version
74+
BUMP_TYPE="patch"
75+
fi
76+
fi
77+
78+
echo "FINAL_BUMP_TYPE=$BUMP_TYPE" >> $GITHUB_OUTPUT
79+
80+
- name: Update package version
81+
run: |
82+
echo "Bumping version: ${{ steps.prepare-version.outputs.FINAL_BUMP_TYPE }}"
83+
npm version ${{ steps.prepare-version.outputs.FINAL_BUMP_TYPE }} --git-tag-version false --save
84+
85+
- name: Commit and push updates
86+
run: |
87+
git config user.name github-actions
88+
git config user.email github-actions@github.com
89+
NEW_VERSION=$(npm pkg get version | tr -d \")
90+
git commit -am "v$NEW_VERSION [skip ci]" && git push
91+
92+
- name: Determine npm dist-tag
93+
id: dist-tag
94+
run: |
95+
# Start with empty publishing args
96+
PUBLISH_ARGS="--access public"
97+
98+
# Check for custom npm tag from input
99+
if [[ -n "${{ inputs.npm_tag }}" ]]; then
100+
DIST_TAG="${{ inputs.npm_tag }}"
101+
echo "Using custom tag: $DIST_TAG"
102+
# Auto-detect based on branch
103+
elif [[ "${{ inputs.branch_name }}" == "main" ]]; then
104+
echo "Publishing from main (latest tag)"
105+
elif [[ "${{ inputs.branch_name }}" =~ release/v([0-9]+) ]]; then
106+
MAJOR_VERSION="${BASH_REMATCH[1]}"
107+
DIST_TAG="v${MAJOR_VERSION}"
108+
echo "Using auto-detected tag for release branch: $DIST_TAG"
109+
else
110+
echo "Branch doesn't match expected patterns, using default tag"
111+
DIST_TAG="dev" # Safe default for non-standard branches
112+
echo "⚠️ WARNING: Using safe default 'dev' tag for non-standard branch"
113+
fi
114+
115+
# Add tag to args if we have one
116+
if [[ -n "$DIST_TAG" ]]; then
117+
PUBLISH_ARGS="$PUBLISH_ARGS --tag $DIST_TAG"
118+
fi
119+
120+
# Add dry-run if specified
121+
if [[ "${{ inputs.dry_run }}" == "true" ]]; then
122+
PUBLISH_ARGS="$PUBLISH_ARGS --dry-run"
123+
echo "DRY RUN MODE - No actual publishing will occur"
124+
fi
125+
126+
# TODO: REMOVE THIS LINE BEFORE MERGING TO MAIN
127+
# Temporary safety measure for testing
128+
PUBLISH_ARGS="$PUBLISH_ARGS --dry-run"
129+
echo "⚠️ TEST MODE: Force using --dry-run flag. Remove before merging to main! ⚠️"
130+
131+
echo "PUBLISH_ARGS=$PUBLISH_ARGS" >> $GITHUB_OUTPUT
132+
NEW_VERSION=$(npm pkg get version | tr -d \")
133+
echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_OUTPUT
134+
135+
- name: Publish to npm
136+
run: |
137+
echo "Publishing version ${{ steps.dist-tag.outputs.NEW_VERSION }} with args: ${{ steps.dist-tag.outputs.PUBLISH_ARGS }}"
138+
npm publish ${{ steps.dist-tag.outputs.PUBLISH_ARGS }}
139+
env:
140+
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}

.github/workflows/publish.yml

Lines changed: 42 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ on:
1313
- minor
1414
- major
1515
npm_tag:
16-
description: 'Custom npm dist-tag (ALWAYS specify for non-standard branches to avoid overwriting latest)'
16+
description: 'Custom npm dist-tag (ALWAYS specify for non-standard branches)'
1717
required: false
1818
default: 'dev'
1919
type: string
@@ -81,144 +81,64 @@ jobs:
8181
- name: Run build
8282
run: npm run build
8383

84-
publish:
85-
name: Publish
84+
determine-version:
85+
name: Determine Version Bump
8686
runs-on: ubuntu-24.04
8787
needs: [build]
88-
environment: production
89-
88+
outputs:
89+
version_bump: ${{ steps.set-bump-type.outputs.version_bump }}
90+
npm_tag: ${{ steps.set-npm-tag.outputs.npm_tag }}
91+
9092
steps:
9193
- name: Check out code
9294
uses: actions/checkout@v4
9395
with:
9496
fetch-depth: 2
95-
ref: ${{ github.ref }}
96-
97-
- name: Restore dependencies
98-
uses: actions/cache/restore@v4
99-
with:
100-
enableCrossOsArchive: true
101-
fail-on-cache-miss: true
102-
key: npm-install-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
103-
path: node_modules
104-
105-
- name: Restore build
106-
uses: actions/cache/restore@v4
107-
with:
108-
enableCrossOsArchive: true
109-
fail-on-cache-miss: true
110-
key: npm-build-${{ runner.os }}-${{ github.sha }}
111-
path: |
112-
.server
113-
.public
114-
115-
- name: Setup Node.js
116-
uses: actions/setup-node@v4
117-
with:
118-
node-version-file: .nvmrc
119-
registry-url: https://registry.npmjs.org
120-
scope: '@defra'
121-
97+
12298
- name: Determine version bump type
123-
id: version-type
99+
id: set-bump-type
124100
run: |
125-
BRANCH_NAME=${GITHUB_REF#refs/heads/}
101+
# Default to patch
102+
VERSION_BUMP="patch"
126103
127-
# Check if this is a manual trigger with inputs
104+
# For manual workflow
128105
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
129-
VERSION_TYPE="${{ github.event.inputs.version_bump }}"
130-
echo "Manual workflow run with version bump: $VERSION_TYPE"
131-
132-
# If a custom npm tag was provided, use it
133-
if [[ -n "${{ github.event.inputs.npm_tag }}" ]]; then
134-
CUSTOM_NPM_TAG="${{ github.event.inputs.npm_tag }}"
135-
echo "Using custom npm tag: $CUSTOM_NPM_TAG"
136-
echo "CUSTOM_NPM_TAG=$CUSTOM_NPM_TAG" >> $GITHUB_OUTPUT
137-
fi
106+
VERSION_BUMP="${{ github.event.inputs.version_bump }}"
107+
echo "Using manual input for version bump: $VERSION_BUMP"
108+
# For automatic trigger
138109
else
139-
# Automatic trigger via push - use commit message logic
140110
COMMIT_MSG=$(git log -1 --pretty=%B)
141-
VERSION_TYPE="patch"
142-
143-
# Check for MINOR or MAJOR in commit message
144111
if [[ "$COMMIT_MSG" == *"MINOR"* ]]; then
145-
VERSION_TYPE="minor"
112+
VERSION_BUMP="minor"
113+
echo "Found MINOR keyword in commit"
146114
elif [[ "$COMMIT_MSG" == *"MAJOR"* ]]; then
147-
VERSION_TYPE="major"
115+
VERSION_BUMP="major"
116+
echo "Found MAJOR keyword in commit"
117+
else
118+
echo "No version keywords found, using patch"
148119
fi
149120
fi
150121
151-
# For release branches, respect the branch naming convention
152-
if [[ "$BRANCH_NAME" =~ release/v([0-9]+) ]]; then
153-
# Extract just the major version number
154-
MAJOR_VERSION="${BASH_REMATCH[1]}"
155-
156-
# Set the package version to match the major version if needed
157-
CURRENT_VERSION=$(npm pkg get version | tr -d \")
158-
CURRENT_MAJOR=$(echo $CURRENT_VERSION | cut -d. -f1)
159-
160-
# If the major version doesn't match, reset to major.0.0
161-
if [[ "$CURRENT_MAJOR" != "$MAJOR_VERSION" ]]; then
162-
npm version $MAJOR_VERSION.0.0 --git-tag-version false --allow-same-version
163-
164-
# Override to patch since we've already set the version
165-
VERSION_TYPE="patch"
166-
fi
167-
fi
168-
169-
echo "VERSION_TYPE=$VERSION_TYPE" >> $GITHUB_OUTPUT
170-
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_OUTPUT
171-
172-
- name: Update package version
173-
run: npm version ${{ steps.version-type.outputs.VERSION_TYPE }} --git-tag-version false --save
174-
175-
- name: Commit and push updates
176-
run: |
177-
git config user.name github-actions
178-
git config user.email github-actions@github.com
179-
NEW_VERSION=$(npm pkg get version | tr -d \")
180-
git commit -am "v$NEW_VERSION [skip ci]" && git push
181-
182-
- name: Publish to npm with appropriate dist-tag
122+
echo "version_bump=$VERSION_BUMP" >> $GITHUB_OUTPUT
123+
124+
- name: Determine npm tag
125+
id: set-npm-tag
183126
run: |
184-
BRANCH_NAME="${{ steps.version-type.outputs.BRANCH_NAME }}"
185-
NEW_VERSION=$(npm pkg get version | tr -d \")
186-
PUBLISH_ARGS="--access public"
187-
188-
# First priority: Check for custom tag from version-type step
189-
if [[ -n "${{ steps.version-type.outputs.CUSTOM_NPM_TAG }}" ]]; then
190-
DIST_TAG="${{ steps.version-type.outputs.CUSTOM_NPM_TAG }}"
191-
PUBLISH_ARGS="$PUBLISH_ARGS --tag $DIST_TAG"
192-
echo "Publishing v$NEW_VERSION with custom tag '$DIST_TAG'"
193-
# Second priority: Check for branch-specific tags
194-
elif [[ "$BRANCH_NAME" == "main" ]]; then
195-
echo "Publishing v$NEW_VERSION from main -> using default 'latest' tag"
196-
elif [[ "$BRANCH_NAME" =~ release/v([0-9]+) ]]; then
197-
MAJOR_VERSION="${BASH_REMATCH[1]}"
198-
DIST_TAG="v${MAJOR_VERSION}"
199-
PUBLISH_ARGS="$PUBLISH_ARGS --tag $DIST_TAG"
200-
echo "Publishing v$NEW_VERSION from $BRANCH_NAME -> using tag '$DIST_TAG'"
201-
else
202-
# Safety check for non-standard branches
203-
if [[ "${{ github.event_name }}" == "workflow_dispatch" && -z "${{ github.event.inputs.npm_tag }}" ]]; then
204-
echo "⚠️ WARNING: Publishing from non-standard branch '$BRANCH_NAME' without a custom npm tag"
205-
echo "⚠️ This will publish as 'latest' and may overwrite your production release"
206-
fi
207-
echo "Branch $BRANCH_NAME doesn't match expected patterns, using default publishing"
127+
# For manual workflow
128+
if [[ "${{ github.event_name }}" == "workflow_dispatch" && -n "${{ github.event.inputs.npm_tag }}" ]]; then
129+
NPM_TAG="${{ github.event.inputs.npm_tag }}"
130+
echo "Using manual input for npm tag: $NPM_TAG"
131+
echo "npm_tag=$NPM_TAG" >> $GITHUB_OUTPUT
208132
fi
209-
210-
# Add dry-run flag if specified
211-
if [[ "${{ github.event.inputs.dry_run }}" == "true" ]]; then
212-
PUBLISH_ARGS="$PUBLISH_ARGS --dry-run"
213-
echo "DRY RUN MODE - No actual publishing will occur"
214-
fi
215-
216-
# TODO: REMOVE THIS LINE BEFORE MERGING TO MAIN
217-
# Temporary safety measure for testing
218-
PUBLISH_ARGS="$PUBLISH_ARGS --dry-run"
219-
echo "⚠️ TEST MODE: Force using --dry-run flag. Remove before merging to main! ⚠️"
220-
221-
# Execute npm publish with all arguments
222-
npm publish $PUBLISH_ARGS
223-
env:
224-
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
133+
134+
publish:
135+
name: Publish Package
136+
needs: [determine-version]
137+
uses: ./.github/workflows/publish-core.yml
138+
with:
139+
version_bump: ${{ needs.determine-version.outputs.version_bump }}
140+
npm_tag: ${{ needs.determine-version.outputs.npm_tag }}
141+
dry_run: ${{ github.event.inputs.dry_run || false }}
142+
branch_name: ${{ github.ref_name }}
143+
secrets:
144+
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}

.github/workflows/version-bump.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Version Bump
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- 'release/v[0-9]*'
8+
9+
jobs:
10+
check-commit:
11+
name: Check Commit for Version Bump
12+
runs-on: ubuntu-24.04
13+
outputs:
14+
should-bump: ${{ steps.check.outputs.should-bump }}
15+
bump-type: ${{ steps.check.outputs.bump-type }}
16+
17+
steps:
18+
- name: Check out code
19+
uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 2
22+
23+
- name: Check for version bump commit
24+
id: check
25+
run: |
26+
COMMIT_MSG=$(git log -1 --pretty=%B)
27+
if [[ "$COMMIT_MSG" =~ (release:|chore\(release\):).*(MINOR|MAJOR) ]]; then
28+
echo "Version bump commit detected"
29+
30+
if [[ "$COMMIT_MSG" == *"MINOR"* ]]; then
31+
echo "Bump type: MINOR"
32+
echo "bump-type=minor" >> $GITHUB_OUTPUT
33+
elif [[ "$COMMIT_MSG" == *"MAJOR"* ]]; then
34+
echo "Bump type: MAJOR"
35+
echo "bump-type=major" >> $GITHUB_OUTPUT
36+
else
37+
echo "Bump type: PATCH (default)"
38+
echo "bump-type=patch" >> $GITHUB_OUTPUT
39+
fi
40+
41+
echo "should-bump=true" >> $GITHUB_OUTPUT
42+
else
43+
echo "Not a version bump commit, skipping"
44+
echo "should-bump=false" >> $GITHUB_OUTPUT
45+
fi
46+
47+
publish:
48+
name: Publish Package
49+
needs: [check-commit]
50+
if: needs.check-commit.outputs.should-bump == 'true'
51+
uses: ./.github/workflows/publish-core.yml
52+
with:
53+
version_bump: ${{ needs.check-commit.outputs.bump-type }}
54+
npm_tag: '' # Will be auto-detected based on branch
55+
dry_run: false
56+
branch_name: ${{ github.ref_name }}
57+
secrets:
58+
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}

0 commit comments

Comments
 (0)