name: Release
on:
push:
tags:
- "v*"
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
permissions:
actions: read
contents: write
id-token: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Wait for CI to finish
uses: actions/github-script@v7
with:
script: |
const headSha = context.sha;
const timeoutMs = 30 * 60 * 1000;
const pollMs = 15 * 1000;
const startedAt = Date.now();
while (true) {
const { data } = await github.rest.actions.listWorkflowRunsForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
head_sha: headSha,
event: 'push',
per_page: 100,
});
const ciRuns = data.workflow_runs.filter((run) => run.name === 'CI');
if (ciRuns.length === 0) {
core.info('No CI runs found for this commit yet; waiting.');
} else {
const pendingRuns = ciRuns.filter((run) => run.status !== 'completed');
if (pendingRuns.length === 0) {
const failedRuns = ciRuns.filter((run) => run.conclusion !== 'success');
if (failedRuns.length > 0) {
core.setFailed(
`CI did not succeed for ${headSha}: ${failedRuns
.map((run) => `${run.html_url} (${run.conclusion})`)
.join(', ')}`,
);
return;
}
core.info(`All CI runs succeeded for ${headSha}.`);
return;
}
core.info(
`Waiting for ${pendingRuns.length} CI run(s): ${pendingRuns
.map((run) => run.html_url)
.join(', ')}`,
);
}
if (Date.now() - startedAt > timeoutMs) {
core.setFailed(`Timed out waiting for CI runs for ${headSha}.`);
return;
}
await new Promise((resolve) => setTimeout(resolve, pollMs));
}
- name: Install Rust
run: rustup toolchain install stable
- name: Run tests
run: cargo test
- uses: rust-lang/crates-io-auth-action@v1.0.4
id: auth
- name: Publish to crates.io
run: cargo publish
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
- name: Create GitHub release
uses: softprops/action-gh-release@v3
with:
generate_release_notes: true
prerelease: ${{ contains(github.ref, '-') }}