Merge branch 'feature/release-v0.4.0' into development #17
Workflow file for this run
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: Crates.io CLI Release | |
| on: | |
| push: | |
| tags: | |
| - "v*.*.*" | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: "Release tag (e.g. v0.3.39)" | |
| required: true | |
| permissions: | |
| contents: read | |
| actions: write | |
| env: | |
| CARGO_TERM_COLOR: always | |
| CLI_CLIENT_SECRET: ${{ secrets.CLI_CLIENT_SECRET }} | |
| jobs: | |
| publish: | |
| name: Publish workspace crates to crates.io | |
| runs-on: ubuntu-latest | |
| outputs: | |
| tag: ${{ steps.release.outputs.tag }} | |
| published_count: ${{ steps.plan.outputs.count }} | |
| publish_cli_sdk_pypi: ${{ steps.downstream.outputs.publish_cli_sdk_pypi }} | |
| publish_cli_sdk_npm: ${{ steps.downstream.outputs.publish_cli_sdk_npm }} | |
| publish_cli_sdk_gem: ${{ steps.downstream.outputs.publish_cli_sdk_gem }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ github.event.inputs.tag || github.ref }} | |
| - name: Set the release version | |
| id: release | |
| shell: bash | |
| run: | | |
| if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then | |
| release_tag="${GITHUB_REF_NAME}" | |
| release_version="${GITHUB_REF_NAME#v}" | |
| else | |
| release_tag="${{ github.event.inputs.tag }}" | |
| release_tag="${release_tag#refs/tags/}" | |
| release_version="${release_tag#v}" | |
| fi | |
| echo "RELEASE_TAG=${release_tag}" >> "$GITHUB_ENV" | |
| echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV" | |
| echo "tag=${release_tag}" >> "$GITHUB_OUTPUT" | |
| echo "version=${release_version}" >> "$GITHUB_OUTPUT" | |
| - name: Read Rust toolchain | |
| shell: bash | |
| run: | | |
| rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)" | |
| if [ -z "$rust_toolchain" ]; then | |
| echo "Failed to read Rust toolchain from rust-toolchain.toml" >&2 | |
| exit 1 | |
| fi | |
| echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV" | |
| - name: Install toolkit | |
| uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 | |
| with: | |
| toolchain: ${{ env.RUST_TOOLCHAIN }} | |
| - name: Setup Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| key: publish | |
| - name: Install cargo-workspaces | |
| shell: bash | |
| run: cargo install cargo-workspaces --version 0.4.2 --locked | |
| - name: Verify workspace crate versions match tag | |
| shell: bash | |
| run: | | |
| cargo metadata --no-deps --format-version 1 > metadata.json | |
| crate_count="$(jq '[.packages[] | select(.manifest_path | contains("/crates/"))] | length' metadata.json)" | |
| if [[ "$crate_count" == "0" ]]; then | |
| echo "::error::No workspace crates found under /crates." | |
| exit 1 | |
| fi | |
| mismatches="$({ | |
| jq -r --arg release_version "${RELEASE_VERSION}" ' | |
| .packages[] | |
| | select(.manifest_path | contains("/crates/")) | |
| | select(.version != $release_version) | |
| | "\(.name) \(.version)"' metadata.json | |
| } || true)" | |
| if [[ -n "$mismatches" ]]; then | |
| echo "::error::These crates do not match tag version ${RELEASE_VERSION}:" | |
| echo "$mismatches" | |
| exit 1 | |
| fi | |
| - name: Build unpublished crate plan | |
| id: plan | |
| shell: bash | |
| env: | |
| CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} | |
| run: | | |
| if [[ -z "${CARGO_REGISTRY_TOKEN}" ]]; then | |
| echo "::error::CARGO_REGISTRY_TOKEN is required." | |
| exit 1 | |
| fi | |
| cargo workspaces plan --skip-published --json --token "${CARGO_REGISTRY_TOKEN}" > plan.json | |
| cat plan.json | |
| plan_count="$(jq 'length' plan.json)" | |
| echo "count=${plan_count}" >> "$GITHUB_OUTPUT" | |
| - name: Derive downstream workflow triggers | |
| id: downstream | |
| shell: bash | |
| run: | | |
| publish_cli_sdk_pypi="$(jq -r 'map(.name) | any(. == "smbcloud-auth-sdk-py" or . == "smbcloud-auth-sdk" or . == "smbcloud-model" or . == "smbcloud-network")' plan.json)" | |
| publish_cli_sdk_npm="$(jq -r 'map(.name) | any(. == "smbcloud-auth-sdk-wasm" or . == "smbcloud-auth-sdk" or . == "smbcloud-network" or . == "smbcloud-networking")' plan.json)" | |
| publish_cli_sdk_gem="$(jq -r 'map(.name) | any(. == "smbcloud-auth-sdk" or . == "smbcloud-model" or . == "smbcloud-network")' plan.json)" | |
| echo "publish_cli_sdk_pypi=${publish_cli_sdk_pypi}" >> "$GITHUB_OUTPUT" | |
| echo "publish_cli_sdk_npm=${publish_cli_sdk_npm}" >> "$GITHUB_OUTPUT" | |
| echo "publish_cli_sdk_gem=${publish_cli_sdk_gem}" >> "$GITHUB_OUTPUT" | |
| echo "SDK PyPI trigger: ${publish_cli_sdk_pypi}" | |
| echo "SDK npm trigger: ${publish_cli_sdk_npm}" | |
| echo "SDK gem trigger: ${publish_cli_sdk_gem}" | |
| - name: Publish workspace crates to crates.io | |
| if: steps.plan.outputs.count != '0' | |
| shell: bash | |
| env: | |
| CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} | |
| run: | | |
| cargo workspaces publish \ | |
| --publish-as-is \ | |
| --yes \ | |
| --locked \ | |
| --allow-branch "*" \ | |
| --publish-interval 15 \ | |
| --token "${CARGO_REGISTRY_TOKEN}" | |
| - name: Nothing to publish | |
| if: steps.plan.outputs.count == '0' | |
| run: echo "All workspace crate versions in this tag are already published." | |
| dispatch-distributions: | |
| name: Trigger CLI distribution workflows | |
| needs: publish | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Trigger GitHub CLI release | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| await github.rest.actions.createWorkflowDispatch({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| workflow_id: 'release-github.yml', | |
| ref: '${{ needs.publish.outputs.tag }}', | |
| inputs: { | |
| tag: '${{ needs.publish.outputs.tag }}' | |
| } | |
| }) | |
| - name: Trigger npm CLI release | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| await github.rest.actions.createWorkflowDispatch({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| workflow_id: 'release-npm.yml', | |
| ref: '${{ needs.publish.outputs.tag }}', | |
| inputs: { | |
| tag: '${{ needs.publish.outputs.tag }}' | |
| } | |
| }) | |
| - name: Trigger NuGet CLI release | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| await github.rest.actions.createWorkflowDispatch({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| workflow_id: 'release-nuget.yml', | |
| ref: '${{ needs.publish.outputs.tag }}', | |
| inputs: { | |
| tag: '${{ needs.publish.outputs.tag }}' | |
| } | |
| }) | |
| - name: Trigger PyPI CLI release | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| await github.rest.actions.createWorkflowDispatch({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| workflow_id: 'release-pypi.yml', | |
| ref: '${{ needs.publish.outputs.tag }}', | |
| inputs: { | |
| tag: '${{ needs.publish.outputs.tag }}' | |
| } | |
| }) | |
| dispatch-sdk-pypi: | |
| name: Trigger SDK PyPI release | |
| needs: publish | |
| if: needs.publish.outputs.publish_cli_sdk_pypi == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Trigger SDK PyPI release workflow | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| await github.rest.actions.createWorkflowDispatch({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| workflow_id: 'release-sdk-pypi.yml', | |
| ref: '${{ needs.publish.outputs.tag }}', | |
| inputs: { | |
| tag: '${{ needs.publish.outputs.tag }}' | |
| } | |
| }) | |
| dispatch-sdk-npm: | |
| name: Trigger SDK npm release | |
| needs: publish | |
| if: needs.publish.outputs.publish_cli_sdk_npm == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Trigger SDK npm release workflow | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| await github.rest.actions.createWorkflowDispatch({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| workflow_id: 'release-sdk-npm.yml', | |
| ref: '${{ needs.publish.outputs.tag }}', | |
| inputs: { | |
| tag: '${{ needs.publish.outputs.tag }}' | |
| } | |
| }) | |
| dispatch-sdk-gem: | |
| name: Trigger SDK Ruby gem release | |
| needs: publish | |
| if: needs.publish.outputs.publish_cli_sdk_gem == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Trigger SDK Ruby gem release workflow | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| await github.rest.actions.createWorkflowDispatch({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| workflow_id: 'release-sdk-gem.yml', | |
| ref: '${{ needs.publish.outputs.tag }}', | |
| inputs: { | |
| tag: '${{ needs.publish.outputs.tag }}' | |
| } | |
| }) |