|
1 | | -name: CI/CD |
| 1 | +name: JavaScript CI/CD |
2 | 2 |
|
3 | 3 | on: |
4 | 4 | push: |
5 | 5 | branches: |
6 | 6 | - main |
7 | 7 | pull_request: |
8 | 8 | types: [opened, synchronize, reopened] |
| 9 | + workflow_dispatch: |
| 10 | + inputs: |
| 11 | + release_mode: |
| 12 | + description: 'Manual release mode' |
| 13 | + required: true |
| 14 | + type: choice |
| 15 | + default: 'instant' |
| 16 | + options: |
| 17 | + - instant |
| 18 | + - changeset-pr |
| 19 | + bump_type: |
| 20 | + description: 'Manual release type' |
| 21 | + required: true |
| 22 | + type: choice |
| 23 | + options: |
| 24 | + - patch |
| 25 | + - minor |
| 26 | + - major |
| 27 | + description: |
| 28 | + description: 'Manual release description (optional)' |
| 29 | + required: false |
| 30 | + type: string |
9 | 31 |
|
10 | 32 | concurrency: ${{ github.workflow }}-${{ github.ref }} |
11 | 33 |
|
|
45 | 67 | name: Test JavaScript |
46 | 68 | runs-on: ubuntu-latest |
47 | 69 | needs: [changeset-check] |
48 | | - if: always() && (github.event_name == 'push' || needs.changeset-check.result == 'success') |
| 70 | + if: always() && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || needs.changeset-check.result == 'success') |
49 | 71 | steps: |
50 | 72 | - uses: actions/checkout@v4 |
51 | 73 |
|
@@ -81,54 +103,12 @@ jobs: |
81 | 103 | working-directory: ./js |
82 | 104 | run: npm test |
83 | 105 |
|
84 | | - # Test Python |
85 | | - test-python: |
86 | | - name: Test Python |
87 | | - runs-on: ubuntu-latest |
88 | | - needs: [changeset-check] |
89 | | - if: always() && (github.event_name == 'push' || needs.changeset-check.result == 'success') |
90 | | - steps: |
91 | | - - uses: actions/checkout@v4 |
92 | | - |
93 | | - - name: Setup Python |
94 | | - uses: actions/setup-python@v5 |
95 | | - with: |
96 | | - python-version: '3.11' |
97 | | - |
98 | | - - name: Setup .NET |
99 | | - uses: actions/setup-dotnet@v4 |
100 | | - with: |
101 | | - dotnet-version: '8.0.x' |
102 | | - |
103 | | - - name: Install clink |
104 | | - run: dotnet tool install --global clink |
105 | | - |
106 | | - - name: Verify clink installation |
107 | | - run: clink --version |
108 | | - |
109 | | - - name: Install dependencies |
110 | | - working-directory: ./python |
111 | | - run: | |
112 | | - python -m pip install --upgrade pip |
113 | | - pip install -e ".[dev]" |
114 | | -
|
115 | | - - name: Create test data directories |
116 | | - run: | |
117 | | - mkdir -p ./python/data |
118 | | - mkdir -p ./data/auth-data/users |
119 | | - mkdir -p ./data/menu-items |
120 | | -
|
121 | | - - name: Run tests |
122 | | - working-directory: ./python |
123 | | - run: pytest |
124 | | - |
125 | 106 | # Release JavaScript - only runs on main after tests pass |
126 | 107 | release-js: |
127 | 108 | name: Release JavaScript |
128 | 109 | runs-on: ubuntu-latest |
129 | | - needs: [test-js, test-python] |
130 | | - # Use always() to ensure this job runs even if changeset-check was skipped |
131 | | - if: always() && github.ref == 'refs/heads/main' && github.event_name == 'push' && needs.test-js.result == 'success' && needs.test-python.result == 'success' |
| 110 | + needs: [test-js] |
| 111 | + if: always() && github.ref == 'refs/heads/main' && github.event_name == 'push' && needs.test-js.result == 'success' |
132 | 112 | permissions: |
133 | 113 | contents: write |
134 | 114 | pull-requests: write |
@@ -213,7 +193,7 @@ jobs: |
213 | 193 | # Get published version |
214 | 194 | PUBLISHED_VERSION=$(node -p "require('./js/package.json').version") |
215 | 195 | echo "published_version=$PUBLISHED_VERSION" >> $GITHUB_OUTPUT |
216 | | - echo "✅ Published @unidel2035/links-client@$PUBLISHED_VERSION to npm" |
| 196 | + echo "✅ Published @link-foundation/links-client@$PUBLISHED_VERSION to npm" |
217 | 197 | env: |
218 | 198 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} |
219 | 199 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} |
@@ -245,3 +225,148 @@ jobs: |
245 | 225 | --repo ${{ github.repository }} |
246 | 226 |
|
247 | 227 | echo "✅ Created GitHub release: $TAG" |
| 228 | +
|
| 229 | + # Manual Instant Release - triggered via workflow_dispatch with instant mode |
| 230 | + instant-release: |
| 231 | + name: Instant Release |
| 232 | + if: github.event_name == 'workflow_dispatch' && github.event.inputs.release_mode == 'instant' |
| 233 | + runs-on: ubuntu-latest |
| 234 | + permissions: |
| 235 | + contents: write |
| 236 | + pull-requests: write |
| 237 | + id-token: write |
| 238 | + steps: |
| 239 | + - uses: actions/checkout@v4 |
| 240 | + with: |
| 241 | + fetch-depth: 0 |
| 242 | + |
| 243 | + - name: Setup Node.js |
| 244 | + uses: actions/setup-node@v4 |
| 245 | + with: |
| 246 | + node-version: '20.x' |
| 247 | + registry-url: 'https://registry.npmjs.org' |
| 248 | + |
| 249 | + - name: Install dependencies |
| 250 | + working-directory: ./js |
| 251 | + run: npm install |
| 252 | + |
| 253 | + - name: Configure git |
| 254 | + run: | |
| 255 | + git config user.name "github-actions[bot]" |
| 256 | + git config user.email "github-actions[bot]@users.noreply.github.com" |
| 257 | +
|
| 258 | + - name: Bump version |
| 259 | + id: version |
| 260 | + run: | |
| 261 | + cd js |
| 262 | +
|
| 263 | + # Get current version |
| 264 | + OLD_VERSION=$(node -p "require('./package.json').version") |
| 265 | + echo "Current version: $OLD_VERSION" |
| 266 | +
|
| 267 | + # Bump version based on bump_type |
| 268 | + npm version ${{ github.event.inputs.bump_type }} --no-git-tag-version |
| 269 | +
|
| 270 | + # Get new version |
| 271 | + NEW_VERSION=$(node -p "require('./package.json').version") |
| 272 | + echo "New version: $NEW_VERSION" |
| 273 | + echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT |
| 274 | +
|
| 275 | + cd .. |
| 276 | +
|
| 277 | + # Commit changes |
| 278 | + git add -A |
| 279 | + git commit -m "$NEW_VERSION" \ |
| 280 | + -m "" \ |
| 281 | + -m "${{ github.event.inputs.description || 'Manual release' }}" \ |
| 282 | + -m "" \ |
| 283 | + -m "🤖 Generated with [Claude Code](https://claude.com/claude-code)" |
| 284 | +
|
| 285 | + git push origin main |
| 286 | + echo "version_committed=true" >> $GITHUB_OUTPUT |
| 287 | +
|
| 288 | + - name: Publish to npm |
| 289 | + if: steps.version.outputs.version_committed == 'true' |
| 290 | + id: publish |
| 291 | + run: | |
| 292 | + cd js && npm publish --access public |
| 293 | + echo "published=true" >> $GITHUB_OUTPUT |
| 294 | + echo "published_version=${{ steps.version.outputs.new_version }}" >> $GITHUB_OUTPUT |
| 295 | + env: |
| 296 | + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} |
| 297 | + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} |
| 298 | + |
| 299 | + - name: Create GitHub Release |
| 300 | + if: steps.publish.outputs.published == 'true' |
| 301 | + env: |
| 302 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 303 | + run: | |
| 304 | + VERSION="${{ steps.version.outputs.new_version }}" |
| 305 | + TAG="v$VERSION" |
| 306 | +
|
| 307 | + gh release create "$TAG" \ |
| 308 | + --title "$VERSION" \ |
| 309 | + --notes "${{ github.event.inputs.description || 'Manual release' }}" \ |
| 310 | + --repo ${{ github.repository }} |
| 311 | +
|
| 312 | + # Manual Changeset PR - creates a pull request with the changeset for review |
| 313 | + changeset-pr: |
| 314 | + name: Create Changeset PR |
| 315 | + if: github.event_name == 'workflow_dispatch' && github.event.inputs.release_mode == 'changeset-pr' |
| 316 | + runs-on: ubuntu-latest |
| 317 | + permissions: |
| 318 | + contents: write |
| 319 | + pull-requests: write |
| 320 | + steps: |
| 321 | + - uses: actions/checkout@v4 |
| 322 | + with: |
| 323 | + fetch-depth: 0 |
| 324 | + |
| 325 | + - name: Setup Node.js |
| 326 | + uses: actions/setup-node@v4 |
| 327 | + with: |
| 328 | + node-version: '20.x' |
| 329 | + |
| 330 | + - name: Install dependencies |
| 331 | + working-directory: ./js |
| 332 | + run: npm install |
| 333 | + |
| 334 | + - name: Create changeset file |
| 335 | + run: | |
| 336 | + CHANGESET_ID=$(date +%s | md5sum | head -c 8) |
| 337 | + CHANGESET_FILE=".changeset/${CHANGESET_ID}.md" |
| 338 | +
|
| 339 | + cat > "$CHANGESET_FILE" << EOF |
| 340 | + --- |
| 341 | + '@link-foundation/links-client': ${{ github.event.inputs.bump_type }} |
| 342 | + --- |
| 343 | +
|
| 344 | + ${{ github.event.inputs.description || 'Manual release' }} |
| 345 | + EOF |
| 346 | +
|
| 347 | + echo "Created changeset: $CHANGESET_FILE" |
| 348 | + cat "$CHANGESET_FILE" |
| 349 | +
|
| 350 | + - name: Create Pull Request |
| 351 | + uses: peter-evans/create-pull-request@v7 |
| 352 | + with: |
| 353 | + token: ${{ secrets.GITHUB_TOKEN }} |
| 354 | + commit-message: 'chore: add changeset for manual ${{ github.event.inputs.bump_type }} release' |
| 355 | + branch: changeset-manual-release-${{ github.run_id }} |
| 356 | + delete-branch: true |
| 357 | + title: 'chore: manual ${{ github.event.inputs.bump_type }} release' |
| 358 | + body: | |
| 359 | + ## Manual Release Request |
| 360 | +
|
| 361 | + This PR was created by a manual workflow trigger to prepare a **${{ github.event.inputs.bump_type }}** release. |
| 362 | +
|
| 363 | + ### Release Details |
| 364 | + - **Type:** ${{ github.event.inputs.bump_type }} |
| 365 | + - **Description:** ${{ github.event.inputs.description || 'Manual release' }} |
| 366 | + - **Triggered by:** @${{ github.actor }} |
| 367 | +
|
| 368 | + ### Next Steps |
| 369 | + 1. Review the changeset in this PR |
| 370 | + 2. Merge this PR to main |
| 371 | + 3. The automated release workflow will create a version PR |
| 372 | + 4. Merge the version PR to publish to npm and create a GitHub release |
0 commit comments