-
-
Notifications
You must be signed in to change notification settings - Fork 15
203 lines (182 loc) · 7.89 KB
/
cli-publish.yml
File metadata and controls
203 lines (182 loc) · 7.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
name: CLI - Publish to npm and GitHub
on:
workflow_dispatch:
inputs:
version_bump:
description: 'Version bump type'
required: true
default: 'patch'
type: choice
options:
- patch
- minor
- major
dry_run:
description: 'Dry run (do not actually publish)'
required: false
default: false
type: boolean
push:
tags:
- 'cli/v*' # Tag push: publish to npm + create GitHub release
#branches:
# - main
paths:
- '.github/workflows/cli-publish.yml'
- 'cli/package.json'
- 'cli/package-lock.json'
permissions:
contents: read
jobs:
publish:
name: Publish CLI to npm
runs-on: ubuntu-latest
permissions:
contents: write # needed to push version bump branch, create PR, and create GitHub release
pull-requests: write # needed to open the version bump PR
id-token: write # required for OIDC authentication to npm registry
defaults:
run:
working-directory: cli
steps:
- name: Harden Runner
uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1
with:
egress-policy: audit
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 24
registry-url: 'https://registry.npmjs.org'
- name: Install extension dependencies
run: npm ci
working-directory: vscode-extension
- name: Install CLI dependencies
run: npm ci
- name: Build production bundle
run: npm run build:production
- name: Validate CLI works
run: node dist/cli.js --help
- name: Determine trigger type
id: trigger_type
env:
EVENT_NAME: ${{ github.event_name }}
GIT_REF: ${{ github.ref }}
run: |
if [[ "$EVENT_NAME" == "push" && "$GIT_REF" == refs/tags/cli/v* ]]; then
echo "is_tag=true" >> "$GITHUB_OUTPUT"
TAG_VERSION=${GIT_REF#refs/tags/cli/v}
echo "tag_version=$TAG_VERSION" >> "$GITHUB_OUTPUT"
echo "Triggered by tag push: cli/v$TAG_VERSION"
else
echo "is_tag=false" >> "$GITHUB_OUTPUT"
echo "tag_version=" >> "$GITHUB_OUTPUT"
echo "Triggered by workflow_dispatch"
fi
working-directory: .
- name: Bump version (workflow_dispatch only)
if: steps.trigger_type.outputs.is_tag != 'true'
run: npm version ${{ inputs.version_bump }} --no-git-tag-version
- name: Verify version matches tag (tag trigger only)
if: steps.trigger_type.outputs.is_tag == 'true'
run: |
PACKAGE_VERSION=$(node -p 'require("./package.json").version')
TAG_VERSION="${{ steps.trigger_type.outputs.tag_version }}"
if [ "$PACKAGE_VERSION" != "$TAG_VERSION" ]; then
echo "❌ Version mismatch!"
echo " package.json: $PACKAGE_VERSION"
echo " tag: $TAG_VERSION"
echo "Please ensure the version in cli/package.json matches the pushed tag."
exit 1
fi
echo "✅ Version check passed: $PACKAGE_VERSION"
- name: Get new version
id: version
run: echo "version=$(node -p 'require("./package.json").version')" >> "$GITHUB_OUTPUT"
- name: Check if version is already published
id: check_published
run: |
PACKAGE_NAME=$(node -p 'require("./package.json").name')
VERSION="${{ steps.version.outputs.version }}"
echo "Checking npm registry for ${PACKAGE_NAME}@${VERSION}..."
if npm view "${PACKAGE_NAME}@${VERSION}" version 2>&1; then
echo "Version ${VERSION} is already published to npm. Skipping publish."
echo "already_published=true" >> "$GITHUB_OUTPUT"
else
echo "Version ${VERSION} is not yet published. Proceeding with publish."
echo "already_published=false" >> "$GITHUB_OUTPUT"
fi
- name: Publish to npm
if: ${{ !inputs.dry_run && steps.check_published.outputs.already_published != 'true' }}
run: NODE_AUTH_TOKEN="" npm publish
- name: Dry run publish
if: ${{ inputs.dry_run }}
run: NODE_AUTH_TOKEN="" npm publish public --dry-run
- name: Commit version bump and create PR
if: ${{ !inputs.dry_run && steps.check_published.outputs.already_published != 'true' && steps.trigger_type.outputs.is_tag != 'true' }}
run: |
cd ..
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git checkout -b cli/bump-version-v${{ steps.version.outputs.version }}
git add cli/package.json cli/package-lock.json
git commit -m "chore(cli): bump version to v${{ steps.version.outputs.version }}"
git push origin cli/bump-version-v${{ steps.version.outputs.version }}
gh pr create \
--title "chore(cli): bump version to v${{ steps.version.outputs.version }}" \
--body "Automated version bump after publishing \`@rajbos/ai-engineering-fluency@${{ steps.version.outputs.version }}\` to npm." \
--base main \
--head cli/bump-version-v${{ steps.version.outputs.version }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Generate release notes
if: ${{ !inputs.dry_run && steps.check_published.outputs.already_published != 'true' && steps.trigger_type.outputs.is_tag == 'true' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG_NAME="cli/v${{ steps.version.outputs.version }}"
echo "Generating release notes for $TAG_NAME..."
if gh api repos/${{ github.repository }}/releases/generate-notes \
-f tag_name="${TAG_NAME}" \
--jq '.body' > /tmp/release_notes.md 2>/dev/null && [ -s /tmp/release_notes.md ]; then
echo "✅ Generated release notes from merged PRs"
else
echo "CLI v${{ steps.version.outputs.version }}" > /tmp/release_notes.md
fi
working-directory: .
- name: Create GitHub release
if: ${{ !inputs.dry_run && steps.check_published.outputs.already_published != 'true' && steps.trigger_type.outputs.is_tag == 'true' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG_NAME="cli/v${{ steps.version.outputs.version }}"
gh release create "$TAG_NAME" \
--title "CLI v${{ steps.version.outputs.version }}" \
--notes-file /tmp/release_notes.md
echo "✅ GitHub release created: $TAG_NAME"
working-directory: .
- name: Summary
run: |
{
if [ "${{ steps.check_published.outputs.already_published }}" = "true" ]; then
echo "## CLI Package Publish Skipped ⏭️"
echo ""
echo "Version **v${{ steps.version.outputs.version }}** is already published to npm."
else
echo "## CLI Package Published 📦"
echo ""
echo "- **Version:** v${{ steps.version.outputs.version }}"
echo "- **Dry run:** ${{ inputs.dry_run }}"
echo ""
if [ "${{ inputs.dry_run }}" = "false" ]; then
echo "Install with: \`npx @rajbos/ai-engineering-fluency\`"
echo ""
if [ "${{ steps.trigger_type.outputs.is_tag }}" = "true" ]; then
echo "A GitHub release has been created: cli/v${{ steps.version.outputs.version }}"
else
echo "A PR has been opened to merge the version bump back to main."
fi
fi
fi
} >> "$GITHUB_STEP_SUMMARY"