release patch (x.x.X) #111
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Publish | |
| run-name: "${{ format('release {0}', inputs.version || inputs.bump) }}" | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| bump: | |
| description: "Version bump type" | |
| required: true | |
| type: choice | |
| default: "patch (x.x.X)" | |
| options: | |
| - "patch (x.x.X)" | |
| - "minor (x.X.0)" | |
| - "major (X.0.0)" | |
| version: | |
| description: "Override version (e.g., 2.0.0-beta.1). Takes precedence over bump." | |
| required: false | |
| type: string | |
| permissions: | |
| contents: write | |
| pull-requests: read | |
| jobs: | |
| bump-versions: | |
| name: Bump versions | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.bump.outputs.version }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Calculate version | |
| id: bump | |
| run: | | |
| # Read current version from packages/cli/package.json (source of truth) | |
| CURRENT_VERSION=$(jq -r '.version' packages/cli/package.json) | |
| echo "📦 Current version: $CURRENT_VERSION" | |
| # Calculate new version | |
| if [ -n "${{ inputs.version }}" ]; then | |
| NEW_VERSION="${{ inputs.version }}" | |
| echo "📌 Using override version: $NEW_VERSION" | |
| else | |
| # Strip any prerelease suffix for calculation | |
| BASE="${CURRENT_VERSION%%-*}" | |
| IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE" | |
| case "${{ inputs.bump }}" in | |
| "major (X.0.0)") | |
| NEW_VERSION="$((MAJOR + 1)).0.0" | |
| ;; | |
| "minor (x.X.0)") | |
| NEW_VERSION="${MAJOR}.$((MINOR + 1)).0" | |
| ;; | |
| *) | |
| NEW_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))" | |
| ;; | |
| esac | |
| echo "🎯 Bump type: ${{ inputs.bump }}" | |
| fi | |
| echo "🚀 New version: $NEW_VERSION" | |
| # Update packages/cli/package.json (version + platform optionalDependencies) | |
| jq --arg v "$NEW_VERSION" '.version = $v | |
| | .optionalDependencies["@tokscale/cli-darwin-arm64"] = $v | |
| | .optionalDependencies["@tokscale/cli-darwin-x64"] = $v | |
| | .optionalDependencies["@tokscale/cli-linux-x64-gnu"] = $v | |
| | .optionalDependencies["@tokscale/cli-linux-x64-musl"] = $v | |
| | .optionalDependencies["@tokscale/cli-linux-arm64-gnu"] = $v | |
| | .optionalDependencies["@tokscale/cli-linux-arm64-musl"] = $v | |
| | .optionalDependencies["@tokscale/cli-win32-x64-msvc"] = $v | |
| | .optionalDependencies["@tokscale/cli-win32-arm64-msvc"] = $v' packages/cli/package.json > tmp.json && mv tmp.json packages/cli/package.json | |
| echo "✅ Updated packages/cli/package.json" | |
| # Update platform package versions | |
| for pkg in \ | |
| cli-darwin-arm64 \ | |
| cli-darwin-x64 \ | |
| cli-linux-x64-gnu \ | |
| cli-linux-x64-musl \ | |
| cli-linux-arm64-gnu \ | |
| cli-linux-arm64-musl \ | |
| cli-win32-x64-msvc \ | |
| cli-win32-arm64-msvc; do | |
| jq --arg v "$NEW_VERSION" '.version = $v' "packages/$pkg/package.json" > tmp.json && mv tmp.json "packages/$pkg/package.json" | |
| echo "✅ Updated packages/$pkg/package.json" | |
| done | |
| # Update packages/tokscale/package.json (version + @tokscale/cli dependency) | |
| jq --arg v "$NEW_VERSION" '.version = $v | .dependencies["@tokscale/cli"] = $v' packages/tokscale/package.json > tmp.json && mv tmp.json packages/tokscale/package.json | |
| echo "✅ Updated packages/tokscale/package.json" | |
| # Verify all versions are updated | |
| echo "" | |
| echo "📋 Verification:" | |
| echo " @tokscale/cli: $(jq -r '.version' packages/cli/package.json)" | |
| echo " tokscale: $(jq -r '.version' packages/tokscale/package.json)" | |
| echo " cli -> darwin arm64: $(jq -r '.optionalDependencies["@tokscale/cli-darwin-arm64"]' packages/cli/package.json)" | |
| echo " tokscale -> cli: $(jq -r '.dependencies["@tokscale/cli"]' packages/tokscale/package.json)" | |
| echo " Platform packages:" | |
| for pkg in cli-darwin-arm64 cli-darwin-x64 cli-linux-x64-gnu cli-linux-x64-musl cli-linux-arm64-gnu cli-linux-arm64-musl cli-win32-x64-msvc cli-win32-arm64-msvc; do | |
| echo " $pkg: $(jq -r '.version' "packages/$pkg/package.json")" | |
| done | |
| echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT | |
| echo "📝 Version bump prepared (will commit after successful publish)" | |
| - name: Upload bumped package.json files | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: bumped-packages | |
| path: | | |
| packages/cli/package.json | |
| packages/cli-darwin-arm64/package.json | |
| packages/cli-darwin-x64/package.json | |
| packages/cli-linux-x64-gnu/package.json | |
| packages/cli-linux-x64-musl/package.json | |
| packages/cli-linux-arm64-gnu/package.json | |
| packages/cli-linux-arm64-musl/package.json | |
| packages/cli-win32-x64-msvc/package.json | |
| packages/cli-win32-arm64-msvc/package.json | |
| packages/tokscale/package.json | |
| retention-days: 1 | |
| build-cli-binary: | |
| name: Build CLI binary - ${{ matrix.settings.target }} | |
| needs: bump-versions | |
| runs-on: ${{ matrix.settings.host }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| settings: | |
| - host: macos-latest | |
| target: x86_64-apple-darwin | |
| package_dir: cli-darwin-x64 | |
| artifact_name: cli-binary-x86_64-apple-darwin | |
| bin_name: tokscale | |
| build: cargo build --release -p tokscale-cli --target x86_64-apple-darwin | |
| strip: strip -x target/x86_64-apple-darwin/release/tokscale | |
| - host: macos-latest | |
| target: aarch64-apple-darwin | |
| package_dir: cli-darwin-arm64 | |
| artifact_name: cli-binary-aarch64-apple-darwin | |
| bin_name: tokscale | |
| build: cargo build --release -p tokscale-cli --target aarch64-apple-darwin | |
| strip: strip -x target/aarch64-apple-darwin/release/tokscale | |
| - host: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| package_dir: cli-linux-x64-gnu | |
| artifact_name: cli-binary-x86_64-unknown-linux-gnu | |
| bin_name: tokscale | |
| build: cargo zigbuild --release -p tokscale-cli --target x86_64-unknown-linux-gnu | |
| strip: strip target/x86_64-unknown-linux-gnu/release/tokscale | |
| - host: ubuntu-latest | |
| target: x86_64-unknown-linux-musl | |
| package_dir: cli-linux-x64-musl | |
| artifact_name: cli-binary-x86_64-unknown-linux-musl | |
| bin_name: tokscale | |
| build: cargo zigbuild --release -p tokscale-cli --target x86_64-unknown-linux-musl | |
| strip: strip target/x86_64-unknown-linux-musl/release/tokscale | |
| - host: ubuntu-latest | |
| target: aarch64-unknown-linux-gnu | |
| package_dir: cli-linux-arm64-gnu | |
| artifact_name: cli-binary-aarch64-unknown-linux-gnu | |
| bin_name: tokscale | |
| build: cargo zigbuild --release -p tokscale-cli --target aarch64-unknown-linux-gnu | |
| strip: aarch64-linux-gnu-strip target/aarch64-unknown-linux-gnu/release/tokscale | |
| - host: ubuntu-latest | |
| target: aarch64-unknown-linux-musl | |
| package_dir: cli-linux-arm64-musl | |
| artifact_name: cli-binary-aarch64-unknown-linux-musl | |
| bin_name: tokscale | |
| build: cargo zigbuild --release -p tokscale-cli --target aarch64-unknown-linux-musl | |
| strip: aarch64-linux-gnu-strip target/aarch64-unknown-linux-musl/release/tokscale | |
| - host: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| package_dir: cli-win32-x64-msvc | |
| artifact_name: cli-binary-x86_64-pc-windows-msvc | |
| bin_name: tokscale.exe | |
| build: cargo build --release -p tokscale-cli --target x86_64-pc-windows-msvc | |
| strip: "" | |
| - host: windows-latest | |
| target: aarch64-pc-windows-msvc | |
| package_dir: cli-win32-arm64-msvc | |
| artifact_name: cli-binary-aarch64-pc-windows-msvc | |
| bin_name: tokscale.exe | |
| build: cargo build --release -p tokscale-cli --target aarch64-pc-windows-msvc | |
| strip: "" | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download bumped package.json files | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: bumped-packages | |
| path: packages/ | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.settings.target }} | |
| - name: Cache cargo | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/bin/ | |
| ~/.cargo/registry/index/ | |
| ~/.cargo/registry/cache/ | |
| ~/.cargo/git/db/ | |
| target/ | |
| key: cli-${{ matrix.settings.target }}-cargo-${{ matrix.settings.host }}-${{ hashFiles('Cargo.lock') }} | |
| - uses: mlugg/setup-zig@v2 | |
| if: ${{ contains(matrix.settings.target, 'linux') }} | |
| with: | |
| version: 0.13.0 | |
| - name: Install cargo-zigbuild | |
| uses: taiki-e/install-action@v2 | |
| if: ${{ contains(matrix.settings.target, 'linux') }} | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| with: | |
| tool: cargo-zigbuild | |
| - name: Build CLI binary | |
| shell: bash | |
| run: ${{ matrix.settings.build }} | |
| - name: Install cross-compilation strip tool | |
| if: contains(matrix.settings.target, 'aarch64') && runner.os == 'Linux' | |
| run: sudo apt-get update && sudo apt-get install -y binutils-aarch64-linux-gnu | |
| - name: Strip CLI binary | |
| if: ${{ matrix.settings.strip != '' }} | |
| shell: bash | |
| run: ${{ matrix.settings.strip }} | |
| - name: Upload CLI binary artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ matrix.settings.artifact_name }} | |
| path: target/${{ matrix.settings.target }}/release/${{ matrix.settings.bin_name }} | |
| if-no-files-found: error | |
| publish-platform-packages: | |
| name: Publish platform package - ${{ matrix.settings.package_name }} | |
| needs: [bump-versions, build-cli-binary] | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| settings: | |
| - package_name: '@tokscale/cli-darwin-x64' | |
| package_dir: cli-darwin-x64 | |
| artifact_name: cli-binary-x86_64-apple-darwin | |
| binary_name: tokscale | |
| - package_name: '@tokscale/cli-darwin-arm64' | |
| package_dir: cli-darwin-arm64 | |
| artifact_name: cli-binary-aarch64-apple-darwin | |
| binary_name: tokscale | |
| - package_name: '@tokscale/cli-linux-x64-gnu' | |
| package_dir: cli-linux-x64-gnu | |
| artifact_name: cli-binary-x86_64-unknown-linux-gnu | |
| binary_name: tokscale | |
| - package_name: '@tokscale/cli-linux-x64-musl' | |
| package_dir: cli-linux-x64-musl | |
| artifact_name: cli-binary-x86_64-unknown-linux-musl | |
| binary_name: tokscale | |
| - package_name: '@tokscale/cli-linux-arm64-gnu' | |
| package_dir: cli-linux-arm64-gnu | |
| artifact_name: cli-binary-aarch64-unknown-linux-gnu | |
| binary_name: tokscale | |
| - package_name: '@tokscale/cli-linux-arm64-musl' | |
| package_dir: cli-linux-arm64-musl | |
| artifact_name: cli-binary-aarch64-unknown-linux-musl | |
| binary_name: tokscale | |
| - package_name: '@tokscale/cli-win32-x64-msvc' | |
| package_dir: cli-win32-x64-msvc | |
| artifact_name: cli-binary-x86_64-pc-windows-msvc | |
| binary_name: tokscale.exe | |
| - package_name: '@tokscale/cli-win32-arm64-msvc' | |
| package_dir: cli-win32-arm64-msvc | |
| artifact_name: cli-binary-aarch64-pc-windows-msvc | |
| binary_name: tokscale.exe | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download bumped package.json files | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: bumped-packages | |
| path: packages/ | |
| - name: Download CLI binary artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: ${{ matrix.settings.artifact_name }} | |
| path: artifacts/${{ matrix.settings.package_dir }} | |
| - name: Prepare package binary | |
| shell: bash | |
| run: | | |
| mkdir -p "packages/${{ matrix.settings.package_dir }}/bin" | |
| cp "artifacts/${{ matrix.settings.package_dir }}/${{ matrix.settings.binary_name }}" "packages/${{ matrix.settings.package_dir }}/bin/${{ matrix.settings.binary_name }}" | |
| if [ "${{ matrix.settings.binary_name }}" = "tokscale" ]; then | |
| chmod +x "packages/${{ matrix.settings.package_dir }}/bin/tokscale" | |
| fi | |
| ls -la "packages/${{ matrix.settings.package_dir }}/bin" | |
| - name: Publish platform package | |
| working-directory: packages/${{ matrix.settings.package_dir }} | |
| run: | | |
| echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc | |
| echo "📦 Publishing ${{ matrix.settings.package_name }} version: $(jq -r '.version' package.json)" | |
| npm publish --access public | |
| env: | |
| NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| publish-cli: | |
| name: Publish @tokscale/cli | |
| needs: [bump-versions, publish-platform-packages] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download bumped package.json files | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: bumped-packages | |
| path: packages/ | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: 1.1.38 | |
| - name: Install dependencies | |
| working-directory: packages/cli | |
| run: bun install | |
| - name: Build CLI | |
| working-directory: packages/cli | |
| run: bun run build | |
| - name: Publish @tokscale/cli | |
| working-directory: packages/cli | |
| run: | | |
| echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc | |
| echo "📦 Publishing version: $(jq -r '.version' package.json)" | |
| npm publish --access public | |
| env: | |
| NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| publish-alias: | |
| name: Publish tokscale (wrapper) | |
| needs: [bump-versions, publish-cli] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download bumped package.json files | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: bumped-packages | |
| path: packages/ | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: 1.1.38 | |
| - name: Publish tokscale | |
| working-directory: packages/tokscale | |
| run: | | |
| echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc | |
| echo "📦 Publishing version: $(jq -r '.version' package.json)" | |
| npm publish --access public | |
| env: | |
| NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| finalize: | |
| name: Commit version bump and create release | |
| needs: [bump-versions, publish-alias] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| persist-credentials: true | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| - name: Download bumped package.json files | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: bumped-packages | |
| path: packages/ | |
| - name: Configure Git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| - name: Commit and push version bump | |
| run: | | |
| NEW_VERSION="${{ needs.bump-versions.outputs.version }}" | |
| echo "📦 Committing version bump to $NEW_VERSION" | |
| git add packages/cli/package.json packages/cli-darwin-arm64/package.json packages/cli-darwin-x64/package.json packages/cli-linux-x64-gnu/package.json packages/cli-linux-x64-musl/package.json packages/cli-linux-arm64-gnu/package.json packages/cli-linux-arm64-musl/package.json packages/cli-win32-x64-msvc/package.json packages/cli-win32-arm64-msvc/package.json packages/tokscale/package.json | |
| git commit -m "chore: bump version to $NEW_VERSION" | |
| git push | |
| echo "✅ Successfully published and committed version $NEW_VERSION" | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: 1.1.38 | |
| - name: Create tag and GitHub release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GITHUB_REPOSITORY: ${{ github.repository }} | |
| run: | | |
| NEW_VERSION="${{ needs.bump-versions.outputs.version }}" | |
| if git rev-parse "v$NEW_VERSION" >/dev/null 2>&1; then | |
| echo "🏷️ Tag v$NEW_VERSION already exists" | |
| else | |
| git tag "v$NEW_VERSION" | |
| git push origin "v$NEW_VERSION" | |
| echo "🏷️ Created tag v$NEW_VERSION" | |
| fi | |
| NOTES_FILE=$(mktemp) | |
| bun scripts/generate-release-notes.ts "$NEW_VERSION" > "$NOTES_FILE" | |
| if gh release view "v$NEW_VERSION" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then | |
| gh release edit "v$NEW_VERSION" \ | |
| --repo "$GITHUB_REPOSITORY" \ | |
| --title "v$NEW_VERSION" \ | |
| --notes-file "$NOTES_FILE" | |
| echo "♻️ Updated existing GitHub release v$NEW_VERSION" | |
| else | |
| gh release create "v$NEW_VERSION" \ | |
| --repo "$GITHUB_REPOSITORY" \ | |
| --title "v$NEW_VERSION" \ | |
| --notes-file "$NOTES_FILE" | |
| echo "🎉 Created GitHub release: https://github.com/${{ github.repository }}/releases/tag/v$NEW_VERSION" | |
| fi | |
| rm -f "$NOTES_FILE" | |
| - name: Post release notes to Discord | |
| if: success() | |
| continue-on-error: true | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_RELEASE_WEBHOOK_URL }} | |
| run: bash scripts/post-discord-release.sh "${{ needs.bump-versions.outputs.version }}" |