release-on-tag (v0.5.0) #9
Workflow file for this run
This file contains 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
# This workflow is subscribed only to the `tag` events, and it assumes that | |
# the version bumps were already done in the `release` workflow. | |
# See the docs/internal/release.md for more details. | |
name: release-on-tag | |
run-name: release-on-tag (${{ github.ref_name }}) | |
on: | |
push: | |
# Match only on specific tags. We don't want this workflow to be invoked when | |
# we put sliding `v{major}` and `v{major}.{minor}` tags on the same commit. | |
tags: ['v[0-9]+.[0-9]+.[0-9]+*'] | |
defaults: | |
run: | |
shell: bash | |
# Contrary to intuition, "contents" covers not only the repository commits | |
# but also GitHub releases. | |
permissions: | |
contents: write | |
# It's technically possible to run several releases in parallel if they are | |
# a regular release and a hotfix from a different branch, but let's try not | |
# to do that for our own sanity (🦶🔫). | |
concurrency: | |
group: ${{ github.workflow }}/${{ github.ref_name }} | |
cancel-in-progress: true | |
jobs: | |
github-release: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: taiki-e/create-gh-release-action@v1 | |
with: | |
changelog: CHANGELOG.md | |
token: ${{ github.token }} | |
build: | |
needs: [github-release] | |
# GitHub doesn't let you split the `${{ }}` syntax into multiple lines 🤦. | |
# Anyway, let's return to the topic... The reason why we pin the specific | |
# versions of OSes is described in the docs under `docs/internal/release.md` | |
runs-on: ${{ contains(matrix.target, 'windows') && 'windows-2019' || contains(matrix.target, 'darwin') && 'macos-11' || 'ubuntu-20.04' }} | |
strategy: | |
# If it happens so that some binaries fail to build, then we can have a | |
# release anyway, but just without those binaries that failed to build. | |
# A build failure, of course would be a very rare event and would be bad, | |
# but it won't be the end of the world. We can rerun the CI job to try again | |
# if it was something flaky. GitHub allows rerunning only the failed jobs. | |
# | |
# If the failure was something deterministic and specific to the platform, | |
# then a new hotfix patch should be created for this. | |
fail-fast: false | |
matrix: | |
include: | |
- { bin: cargo-marker, target: x86_64-pc-windows-msvc } | |
- { bin: cargo-marker, target: x86_64-apple-darwin } | |
- { bin: cargo-marker, target: x86_64-unknown-linux-gnu } | |
- { bin: cargo-marker, target: x86_64-unknown-linux-musl } | |
# Who could know that cross-compiling for ARM on windows and macos "just works"?! | |
# I hope one day it will just work for Linux too, but that's really surprising to | |
# see how windows and macos beat linux in this regard 👀. | |
# | |
# We use `cargo-zigbuild` instead of the default `cross` build tool because the latter | |
# is more heavyweight as it depends on `docker`, but `cargo-zigbuild` doesn't. | |
- { bin: cargo-marker, target: aarch64-pc-windows-msvc } | |
- { bin: cargo-marker, target: aarch64-apple-darwin } | |
- { bin: cargo-marker, target: aarch64-unknown-linux-gnu, build_tool: cargo-zigbuild } | |
- { bin: cargo-marker, target: aarch64-unknown-linux-musl, build_tool: cargo-zigbuild } | |
# Unfortunatelly, the driver depends on the dynamic libraries `rustc_driver` and `LLVM`. | |
# It means we can't have a static `musl` binary for it. It also significantly complicates | |
# the build for the ARM targets, so in this matrix we have only x86_64 targets. The ARM | |
# build is handled in a separate job. | |
- { bin: marker_rustc_driver, target: x86_64-pc-windows-msvc } | |
- { bin: marker_rustc_driver, target: x86_64-apple-darwin } | |
- { bin: marker_rustc_driver, target: x86_64-unknown-linux-gnu } | |
env: | |
MARKER_ALLOW_DRIVER_BUILD: 1 | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions-rust-lang/setup-rust-toolchain@v1 | |
with: | |
# Release is a rare event. We don't need any caching for it, | |
# and even if we did use the cache it would already be evicted | |
# at the time we run the next release because GitHub clears the | |
# cache after 7 days of inactivity. | |
cache: false | |
target: ${{ matrix.target }} | |
- uses: taiki-e/upload-rust-binary-action@v1 | |
with: | |
bin: ${{ matrix.bin }} | |
target: ${{ matrix.target }} | |
token: ${{ github.token }} | |
checksum: sha256 | |
tar: all | |
zip: all | |
build_tool: ${{ matrix.build_tool || 'cargo' }} | |
# This job is the result of desperation. Unfortunatelly we can't easily cross-compile | |
# the driver for ARM targets, because we need to have the `rustc_private` DLLs to | |
# be compiled for ARM, but their proc macros need to be compiled for the host x86_64 | |
# architecture. However, this isn't the case today, and those proc macros are distributed | |
# pre-compiled only for the architecture of the target machine by `rustup`. | |
# | |
# So this job uses docker + QEMU to emulate an ARM machine and build the driver there. | |
# This, however, is a very slow process, and it's not possible to use this approach | |
# to build the driver for windows and macos that easily. I have high confidence it's | |
# possible to hack something for windows, but given the Apple's closed ecosystem... | |
# | |
# I don't think it's reasonably possible to compile for macos ARM. They really want | |
# you to buy their hardware. There is a gossip that GitHub will provide Apple M1 managed | |
# runners somewhere in the observable future, but until that happens the only option | |
# to compile for macos on ARM is to buy an Apple M1 machine and make a self-hosted runner, | |
# but that is ridiculously expensive. | |
# https://github.com/actions/runner/issues/805#issuecomment-1438149537 | |
# | |
# See also the discussion in zulip: | |
# https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Cross-compile.20with.20rustc_private | |
build-driver-on-arm: | |
needs: [github-release] | |
runs-on: ubuntu-20.04 | |
env: | |
artifact: marker_rustc_driver-aarch64-unknown-linux-gnu | |
# We've seen this job hang for 6 hours with the logs ending with | |
# ``` | |
# Compiling libloading v0.8.0 | |
# Compiling bumpalo v3.14.0 | |
# Error: The operation was canceled. | |
# ``` | |
# | |
# No idea how that happens. Maybe that's a bug with the compiler hang in rustc, | |
# but this bug seems flaky, and reruning the job if it hangs should help | |
timeout-minutes: 60 | |
steps: | |
- uses: actions/checkout@v4 | |
# Concatenate dependent bash files. Unfortunately, the install script | |
# runs without the repository mounted, so we have to do this to not | |
# use anything from the repo. | |
- run: | | |
cat <<EOF >> $GITHUB_ENV | |
install_script<<DELIM | |
rust_version=$(sed -n 's/^channel\s*=\s*"\(.*\)"/\1/p' rust-toolchain.toml) | |
$(cat scripts/lib.sh scripts/release/qemu-setup.sh) | |
DELIM | |
EOF | |
- uses: uraimo/run-on-arch-action@v2 | |
with: | |
arch: aarch64 | |
distro: ubuntu20.04 | |
dockerRunArgs: --volume ./artifacts:/artifacts | |
setup: mkdir -p artifacts | |
install: ${{ env.install_script }} | |
env: | | |
MARKER_ALLOW_DRIVER_BUILD: 1 | |
# Produce a binary artifact and place it in the mounted volume | |
run: | | |
export PATH="/root/.cargo/bin:$PATH" | |
cargo build -p marker_rustc_driver --release | |
cp target/release/marker_rustc_driver /artifacts/marker_rustc_driver | |
- run: ../scripts/release/upload.sh ${{ github.ref_name }} marker_rustc_driver ${{ env.artifact }} | |
working-directory: artifacts | |
env: | |
GH_TOKEN: ${{ github.token }} | |
# Publish the crates to crates.io | |
crates-io: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions-rust-lang/setup-rust-toolchain@v1 | |
with: { cache: false } | |
- run: ./scripts/download/cargo-release.sh | |
# For extra security we set the env variable with the token only | |
# for the steps that require them. | |
# | |
# We used to have two `cargo release` invocations here. One without the | |
# `cargo_marker` package, and one with it. This was done because there is | |
# an implicit dependency between `cargo_marker` and `marker_rustc_driver`, | |
# since the former installs the latter. However, this separation somehow | |
# resulted in the second `cargo release` invocation to fail with the error | |
# ``` | |
# the remote server responded with an error (status 403 Forbidden): | |
# must be logged in to perform that action | |
# ``` | |
# | |
# No idea why this happens, but let's just keep a single cargo release | |
# to avoid this issue and to simplify the workflow, because the problem | |
# we tried to protect against is not that likely to happen anyway. | |
- run: cargo release publish --execute --no-confirm --no-verify --allow-branch '*' | |
env: | |
CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }} |