Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions .github/workflows/homebrew.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,31 @@ jobs:
# from third-party taps with an UntrustedTapError. A plain file edit
# sidesteps `brew` entirely and never hits the trust check.
- name: Bump tap formula
# Non-blocking: needs a valid HOMEBREW_TAP_TOKEN. If the token is
# missing/expired the bump fails here, but the calling release run
# stays green (the binaries + checksums have already published). Fix
# the token and re-run to bump the tap.
continue-on-error: true
# Pushes with a deploy key that can write to borghei/homebrew-tap and
# nothing else (secret HOMEBREW_TAP_DEPLOY_KEY; public half is a
# read-write deploy key on the tap). No personal access token, so there
# is nothing to expire. A failure here is real and fails the job: the
# binaries have already published, so fix the cause and re-run this
# workflow by hand with the tag (workflow_dispatch).
env:
TAG: ${{ inputs.tag }}
TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
TAP_DEPLOY_KEY: ${{ secrets.HOMEBREW_TAP_DEPLOY_KEY }}
run: |
set -euo pipefail
VERSION="${TAG#v}"
echo "Bumping borghei/tap ink formula to ${VERSION}"

git clone "https://x-access-token:${TAP_TOKEN}@github.com/borghei/homebrew-tap.git" tap
if [ -z "$TAP_DEPLOY_KEY" ]; then
echo "::error::HOMEBREW_TAP_DEPLOY_KEY secret is not set; cannot bump the tap."
exit 1
fi
install -m 700 -d ~/.ssh
printf '%s\n' "$TAP_DEPLOY_KEY" > ~/.ssh/tap_deploy_key
chmod 600 ~/.ssh/tap_deploy_key
ssh-keyscan -t ed25519 github.com >> ~/.ssh/known_hosts 2>/dev/null
export GIT_SSH_COMMAND="ssh -i ~/.ssh/tap_deploy_key -o IdentitiesOnly=yes"

git clone git@github.com:borghei/homebrew-tap.git tap
F=tap/Formula/ink.rb

# Bump the version field and the version embedded in every download URL.
Expand All @@ -59,6 +70,9 @@ jobs:
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
if git diff --quiet; then
# Still prove the key can write, so a broken key is found now and
# not at the next release.
git push --dry-run origin HEAD
echo "Formula already up to date — nothing to push."
exit 0
fi
Expand Down
46 changes: 33 additions & 13 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -453,36 +453,56 @@ jobs:

# Publish the crate so `cargo install ink-md` (and mise's cargo backend)
# track releases instead of going stale (issue #4: crates.io sat at 0.2.1
# while binaries reached 0.6.x). Skips cleanly when the token secret is
# absent; never fails the release — the binaries have already published.
# while binaries reached 0.6.x). A failure here is loud on purpose: the
# binaries have already published, so fix the cause and re-run the job.
crates:
needs: release
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
# Tag pushes publish. A manual run (workflow_dispatch) only rehearses:
# it does the token exchange and a `cargo publish --dry-run`.
if: >-
always() &&
((github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && needs.release.result == 'success')
|| github.event_name == 'workflow_dispatch')
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # OIDC token for crates.io Trusted Publishing
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
# Trusted Publishing: crates.io trusts this repository's release.yml
# (configured on the crate), so there is no long-lived token to store
# or rotate. The action swaps the job's OIDC token for a short-lived
# crates.io token and revokes it when the job ends.
- uses: rust-lang/crates-io-auth-action@v1
id: auth
- name: Publish to crates.io
continue-on-error: true
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }}
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
run: |
if [ -z "$CARGO_REGISTRY_TOKEN" ]; then
echo "No CRATES_IO_TOKEN secret — skipping crates.io publish."
set -euo pipefail
version=$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -1)
if [ "$GITHUB_EVENT_NAME" != "push" ]; then
echo "Manual run: rehearsing only."
cargo publish --dry-run --locked
exit 0
fi
# Re-running a release must not fail because the version is already up.
code=$(curl -s -o /dev/null -w '%{http_code}' -A "ink-release (github.com/borghei/ink)" \
"https://crates.io/api/v1/crates/ink-md/${version}")
if [ "$code" = "200" ]; then
echo "ink-md ${version} is already on crates.io — nothing to publish."
exit 0
fi
cargo publish
cargo publish --locked

# Bump the Homebrew tap formula in the same run. Chaining via `needs` (rather
# than a `release: published` trigger on homebrew.yml) is deliberate: releases
# created with the default GITHUB_TOKEN do not emit events that trigger other
# workflows, so a `release`-triggered bump would silently never fire.
#
# The bump is made non-blocking inside homebrew.yml (its step is
# continue-on-error): a missing/expired HOMEBREW_TAP_TOKEN fails the bump but
# not the release, since the binaries + checksums have already published.
# (`continue-on-error` is not valid on a reusable-workflow-call job, so the
# tolerance lives on the step instead.)
# The bump pushes with a deploy key (secret HOMEBREW_TAP_DEPLOY_KEY) and
# fails loudly if it cannot; re-run homebrew.yml by hand with the tag.
homebrew:
needs: release
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
Expand Down
Loading