Skip to content

Merge branch 'feature/release-v0.4.0' into development #17

Merge branch 'feature/release-v0.4.0' into development

Merge branch 'feature/release-v0.4.0' into development #17

Workflow file for this run

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 }}'
}
})