chore: bump version to 0.3.0-rc.9 (#220) #15
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
| # This file was autogenerated by dist: https://axodotdev.github.io/cargo-dist | |
| # | |
| # Copyright 2022-2024, axodotdev | |
| # SPDX-License-Identifier: MIT or Apache-2.0 | |
| # | |
| # CI that: | |
| # | |
| # * checks for a Git Tag that looks like a release | |
| # * builds artifacts with dist (archives, installers, hashes) | |
| # * uploads those artifacts to temporary workflow zip | |
| # * on success, uploads the artifacts to a GitHub Release | |
| # | |
| # Note that the GitHub Release will be created with a generated | |
| # title/body based on your changelogs. | |
| name: Release | |
| permissions: | |
| "contents": "write" | |
| # This task will run whenever you push a git tag that looks like a version | |
| # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. | |
| # Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where | |
| # PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION | |
| # must be a Cargo-style SemVer Version (must have at least major.minor.patch). | |
| # | |
| # If PACKAGE_NAME is specified, then the announcement will be for that | |
| # package (erroring out if it doesn't have the given version or isn't dist-able). | |
| # | |
| # If PACKAGE_NAME isn't specified, then the announcement will be for all | |
| # (dist-able) packages in the workspace with that version (this mode is | |
| # intended for workspaces with only one dist-able package, or with all dist-able | |
| # packages versioned/released in lockstep). | |
| # | |
| # If you push multiple tags at once, separate instances of this workflow will | |
| # spin up, creating an independent announcement for each one. However, GitHub | |
| # will hard limit this to 3 tags per commit, as it will assume more tags is a | |
| # mistake. | |
| # | |
| # If there's a prerelease-style suffix to the version, then the release(s) | |
| # will be marked as a prerelease. | |
| on: | |
| # Tag-push only. We want the release pipeline off the critical path | |
| # for day-to-day PRs — `pr-run-mode = "skip"` in | |
| # `dist-workspace.toml` would still let us add a `pull_request:` | |
| # trigger later (the matrix would emit no jobs), but for now nothing | |
| # in the repo benefits from validating the workflow on every PR so | |
| # we keep the trigger surface minimal. | |
| push: | |
| # GitHub Actions tag filters are **glob/minimatch**, not regex — | |
| # `+` would be matched literally. Use `*` (zero-or-more of any | |
| # char) so both `v0.0.2` and `v0.3.0-rc1` match. Copilot caught | |
| # the original regex-style pattern in PR #162 review. | |
| tags: | |
| - 'v[0-9]*.[0-9]*.[0-9]*' | |
| jobs: | |
| # Run 'dist plan' (or host) to determine what tasks we need to do | |
| plan: | |
| runs-on: "ubuntu-22.04" | |
| outputs: | |
| val: ${{ steps.plan.outputs.manifest }} | |
| # `tag` is the git tag (e.g. `v0.3.0-rc1`) used downstream as | |
| # the GitHub release tag. `tag-flag` is the same tag wrapped as | |
| # `--tag=<value>` for every `dist` invocation. (Pre-cutover-3 | |
| # the Rust pipeline lived under an `rs-` namespace and these two | |
| # outputs differed; with the namespace removed they're now the | |
| # same value, but keeping both names lets the downstream jobs | |
| # stay byte-identical to the cargo-dist 0.31 template.) | |
| tag: ${{ steps.tags.outputs.tag }} | |
| tag-flag: ${{ steps.tags.outputs.tag-flag }} | |
| publishing: ${{ !github.event.pull_request }} | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| submodules: recursive | |
| - id: tags | |
| # Compute the tag value once and reuse it across every | |
| # downstream `dist` call. On a pull_request event (currently | |
| # unreachable — the workflow's `on:` block only lists | |
| # `push.tags` — but kept defensive in case we re-enable PR | |
| # validation later) we emit empty strings, mirroring | |
| # cargo-dist's original generator behaviour. | |
| shell: bash | |
| run: | | |
| if [ -z "${{ github.event.pull_request }}" ]; then | |
| FULL_TAG="${{ github.ref_name }}" | |
| echo "tag=${FULL_TAG}" >> "$GITHUB_OUTPUT" | |
| echo "tag-flag=--tag=${FULL_TAG}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "tag=" >> "$GITHUB_OUTPUT" | |
| echo "tag-flag=" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Install dist | |
| # we specify bash to get pipefail; it guards against the `curl` command | |
| # failing. otherwise `sh` won't catch that `curl` returned non-0 | |
| shell: bash | |
| run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.31.0/cargo-dist-installer.sh | sh" | |
| - name: Cache dist | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: cargo-dist-cache | |
| path: ~/.cargo/bin/dist | |
| # sure would be cool if github gave us proper conditionals... | |
| # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible | |
| # functionality based on whether this is a pull_request, and whether it's from a fork. | |
| # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* | |
| # but also really annoying to build CI around when it needs secrets to work right.) | |
| - id: plan | |
| # Write the plan manifest into the workspace root, NOT into | |
| # `target/distrib/`. Bash creates the redirect target as an | |
| # empty file BEFORE `dist` runs; `dist` calls `load_manifests` | |
| # over its `dist_dir` (= `target/distrib/`) and tries to parse | |
| # every `*dist-manifest.json` file it finds there. An empty | |
| # file makes axoasset bail with `failed to parse JSON / EOF | |
| # while parsing a value at line 1 column 0`. Matches the | |
| # upstream cargo-dist 0.31 template, which also keeps | |
| # `plan-dist-manifest.json` at the workspace root for the same | |
| # reason. | |
| shell: bash | |
| run: | | |
| if [ -z "${{ github.event.pull_request }}" ]; then | |
| DIST_SUBCOMMAND="host --steps=create ${{ steps.tags.outputs.tag-flag }}" | |
| else | |
| DIST_SUBCOMMAND="plan" | |
| fi | |
| dist $DIST_SUBCOMMAND --output-format=json > plan-dist-manifest.json | |
| echo "dist ran successfully" | |
| cat plan-dist-manifest.json | |
| echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" | |
| - name: "Upload dist-manifest.json" | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: artifacts-plan-dist-manifest | |
| path: plan-dist-manifest.json | |
| # Build and packages all the platform-specific things | |
| build-local-artifacts: | |
| name: build-local-artifacts (${{ join(matrix.targets, ', ') }}) | |
| # Let the initial task tell us to not run (currently very blunt) | |
| needs: | |
| - plan | |
| if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null && (needs.plan.outputs.publishing == 'true' || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == 'upload') }} | |
| strategy: | |
| fail-fast: false | |
| # Target platforms/runners are computed by dist in create-release. | |
| # Each member of the matrix has the following arguments: | |
| # | |
| # - runner: the github runner | |
| # - dist-args: cli flags to pass to dist | |
| # - install-dist: expression to run to install dist on the runner | |
| # | |
| # Typically there will be: | |
| # - 1 "global" task that builds universal installers | |
| # - N "local" tasks that build each platform's binaries and platform-specific installers | |
| matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }} | |
| runs-on: ${{ matrix.runner }} | |
| container: ${{ matrix.container && matrix.container.image || null }} | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # Workspace-relative path; both the shell steps below and the | |
| # upload-artifact `path:` resolve from `$GITHUB_WORKSPACE`, so | |
| # one definition serves both consumers. | |
| BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json | |
| steps: | |
| - name: enable windows longpaths | |
| run: | | |
| git config --global core.longpaths true | |
| - uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| submodules: recursive | |
| - name: Install Rust non-interactively if not already installed | |
| if: ${{ matrix.container }} | |
| run: | | |
| if ! command -v cargo > /dev/null 2>&1; then | |
| curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y | |
| echo "$HOME/.cargo/bin" >> $GITHUB_PATH | |
| fi | |
| - name: Install dist | |
| run: ${{ matrix.install_dist.run }} | |
| # Get the dist-manifest. Extract to the workspace root: upload-artifact | |
| # preserves each entry's workspace-relative path inside the artifact, so | |
| # the uploads carry `target/distrib/...` and the download restores them | |
| # at the workspace root. | |
| - name: Fetch local artifacts | |
| uses: actions/download-artifact@v7 | |
| with: | |
| pattern: artifacts-* | |
| path: . | |
| merge-multiple: true | |
| - name: Install dependencies | |
| run: | | |
| ${{ matrix.packages_install }} | |
| - name: Build artifacts | |
| shell: bash | |
| run: | | |
| # Pin the version slug to the tag (e.g. `0.3.0-rc.1`) so the | |
| # title-bar chrome reads the actual release version instead | |
| # of `git describe --always`'s commit-hash fallback — | |
| # Actions checkouts are shallow and often can't see any | |
| # `v*` tag, even though the workflow itself was triggered by | |
| # one. `build.rs` consumes `CODESCOPE_VERSION` as an | |
| # override; strip the leading `v` so the slug renders as | |
| # `V0.3.0-rc.1` (build.rs adds the `V` prefix at render | |
| # time). | |
| FULL_TAG="${GITHUB_REF_NAME}" | |
| STRIPPED_VERSION="${FULL_TAG#v}" | |
| export CODESCOPE_VERSION="${STRIPPED_VERSION}" | |
| echo "Building with CODESCOPE_VERSION=${CODESCOPE_VERSION}" | |
| # Actually do builds and make zips and whatnot | |
| dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json | |
| echo "dist ran successfully" | |
| - id: cargo-dist | |
| name: Post-build | |
| # We force bash here just because github makes it really hard to get values up | |
| # to "real" actions without writing to env-vars, and writing to env-vars has | |
| # inconsistent syntax between shell and powershell. | |
| shell: bash | |
| run: | | |
| # Parse out what we just built and upload it to scratch storage. | |
| # `dist print-upload-files-from-manifest` emits ABSOLUTE paths | |
| # (e.g. `D:\a\CodeScope\CodeScope\target\distrib\foo.msi` on | |
| # Windows, `/home/runner/.../target/distrib/foo.tar.xz` on | |
| # Linux/macOS). Normalize backslashes → forward slashes | |
| # first (Windows paths), then strip everything up to and | |
| # including the leading runner-specific prefix so we end up | |
| # with workspace-relative `target/distrib/foo.msi`. | |
| # After `host` fetches everything into `artifacts/` and | |
| # flattens, the basenames land at `artifacts/<basename>` for | |
| # `gh release create artifacts/*`. | |
| echo "paths<<EOF" >> "$GITHUB_OUTPUT" | |
| dist print-upload-files-from-manifest --manifest dist-manifest.json \ | |
| | tr '\\' '/' \ | |
| | sed 's|^.*/target/|target/|' \ | |
| >> "$GITHUB_OUTPUT" | |
| echo "EOF" >> "$GITHUB_OUTPUT" | |
| # Echo the rewritten paths for debugging (next runs grep this). | |
| echo "Upload paths (post-rewrite):" | |
| dist print-upload-files-from-manifest --manifest dist-manifest.json \ | |
| | tr '\\' '/' \ | |
| | sed 's|^.*/target/|target/|' | |
| cp dist-manifest.json "$BUILD_MANIFEST_NAME" | |
| # --------------------------------------------------------------- | |
| # Velopack packaging — cross-platform. | |
| # | |
| # The velopack-rs bridge (`src/velopack_bridge.rs`) picks its | |
| # update channel per target triple (`win` / `osx-arm64` / | |
| # `osx-x64` / `linux-x64`); the steps below emit one Velopack | |
| # feed per channel so each running build only ever pulls its own | |
| # platform's assets. | |
| # | |
| # Each runner produces Velopack's canonical feed asset | |
| # `releases.<channel>.json` (what `GithubSource` resolves via | |
| # `CoreUtil.GetVeloReleaseIndexName(channel)` → | |
| # `releases.<channel>.json`, see velopack/velopack | |
| # `Sources/GitBase.cs`), the legacy text-format `RELEASES`-style | |
| # file, the `Full.nupkg` package (and a `Delta.nupkg` from the | |
| # second release onward), and the per-platform installer / bundle: | |
| # | |
| # * Windows → `*-win-Setup.exe` | |
| # * macOS → `*.app.zip` (signed only when --signAppIdentity is | |
| # supplied; unsigned here pending an Apple Developer account | |
| # — user accepted the patient-iteration trade-off) | |
| # * Linux → `*.AppImage` | |
| # | |
| # The `Compute velopack params` step short-circuits unrecognised | |
| # triples (sets `supported=false`) so a future matrix entry doesn't | |
| # break the build — every velopack step gates on | |
| # `steps.velopack-params.outputs.supported == 'true'`. | |
| # --------------------------------------------------------------- | |
| - name: Compute velopack params | |
| id: velopack-params | |
| shell: bash | |
| env: | |
| # `matrix.targets` is an array; `build-local-artifacts` only | |
| # ever populates a single entry per matrix row (the cargo-dist | |
| # convention), so `[0]` is the build target triple. | |
| TARGET: ${{ matrix.targets[0] }} | |
| run: | | |
| # Channel + binary basename + bundle id (macOS only) per | |
| # triple. Keep this in lockstep with | |
| # `src/velopack_bridge.rs::default_channel` — a mismatch | |
| # means the client polls a feed the pipeline never | |
| # published. | |
| case "$TARGET" in | |
| x86_64-pc-windows-msvc) | |
| channel=win; mainExe=codescope-rs.exe; bundleId="" ;; | |
| aarch64-apple-darwin) | |
| channel=osx-arm64; mainExe=codescope-rs; bundleId=com.maui1911.codescope-rs ;; | |
| x86_64-apple-darwin) | |
| channel=osx-x64; mainExe=codescope-rs; bundleId=com.maui1911.codescope-rs ;; | |
| x86_64-unknown-linux-gnu) | |
| channel=linux-x64; mainExe=codescope-rs; bundleId="" ;; | |
| *) | |
| echo "Skipping velopack pack for unrecognised target: $TARGET" | |
| echo "supported=false" >> "$GITHUB_OUTPUT" | |
| exit 0 ;; | |
| esac | |
| echo "channel=$channel" >> "$GITHUB_OUTPUT" | |
| echo "mainExe=$mainExe" >> "$GITHUB_OUTPUT" | |
| echo "bundleId=$bundleId" >> "$GITHUB_OUTPUT" | |
| echo "supported=true" >> "$GITHUB_OUTPUT" | |
| echo "Velopack params: channel=$channel mainExe=$mainExe bundleId=$bundleId" | |
| - name: Setup .NET (for vpk) | |
| if: steps.velopack-params.outputs.supported == 'true' | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '8.0.x' | |
| - name: Install vpk | |
| if: steps.velopack-params.outputs.supported == 'true' | |
| shell: bash | |
| run: | | |
| dotnet tool install -g vpk | |
| # setup-dotnet@v4 adds `$HOME/.dotnet/tools` to PATH on | |
| # Windows, but on macOS/Linux the export is per-shell — make | |
| # it persistent for subsequent steps via `$GITHUB_PATH`. | |
| if [ "$RUNNER_OS" != "Windows" ]; then | |
| echo "$HOME/.dotnet/tools" >> "$GITHUB_PATH" | |
| fi | |
| - name: Stage Velopack publish dir | |
| # cargo-dist already built the release binary at | |
| # `target/<triple>/{dist,release}/<mainExe>`. vpk wants a flat | |
| # publish dir that contains the main binary plus any | |
| # side-by-side files. Today the build is statically linked so | |
| # just the binary is enough — but we also pick up sibling | |
| # `.dll`/`.dylib`/`.so` files cargo might emit so a future | |
| # dynamically-linked sidecar gets bundled automatically. | |
| if: steps.velopack-params.outputs.supported == 'true' | |
| shell: bash | |
| env: | |
| TARGET: ${{ matrix.targets[0] }} | |
| MAIN_EXE: ${{ steps.velopack-params.outputs.mainExe }} | |
| run: | | |
| publish="target/distrib/velopack/publish" | |
| mkdir -p "$publish" | |
| # Pre-list every matching binary for debugging — fast hint | |
| # if a future cargo-dist profile change moves the output. | |
| echo "Searching target/ for $MAIN_EXE..." | |
| find target -type f -name "$MAIN_EXE" 2>/dev/null | sed 's|^| found: |' | |
| # Filter to the build for *this* triple landed under either | |
| # `dist/` (cargo-dist 0.31 profile) or `release/` (older). | |
| src_exe=$(find target -type f -name "$MAIN_EXE" 2>/dev/null \ | |
| | grep "/$TARGET/" \ | |
| | grep -E '/(dist|release)/' \ | |
| | head -n 1 || true) | |
| if [ -z "$src_exe" ]; then | |
| echo "ERROR: no release build of $MAIN_EXE under target/$TARGET/<dist|release>/" | |
| exit 1 | |
| fi | |
| echo "Staging velopack publish from $(dirname "$src_exe")" | |
| cp "$src_exe" "$publish/" | |
| chmod +x "$publish/$MAIN_EXE" | |
| # Side-by-side native libs cargo might emit. The patterns | |
| # cover Windows / macOS / Linux without globbing the wrong | |
| # extension on a given runner. | |
| shopt -s nullglob | |
| for ext in dll dylib so; do | |
| for f in "$(dirname "$src_exe")"/*."$ext"; do | |
| cp "$f" "$publish/" | |
| done | |
| done | |
| ls -la "$publish" | |
| - name: Download prior Velopack release (for delta) | |
| # Best-effort: pulls the latest GitHub release's velopack assets | |
| # into `releases/` so `vpk pack` can compute a Delta.nupkg. | |
| # First release on any channel just no-ops (no prior to diff | |
| # against) and `vpk pack` emits only a Full.nupkg, which is | |
| # fine. Keep `continue-on-error` so a missing/private prior | |
| # release doesn't abort the whole pipeline. | |
| if: steps.velopack-params.outputs.supported == 'true' | |
| continue-on-error: true | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| CHANNEL: ${{ steps.velopack-params.outputs.channel }} | |
| run: | | |
| mkdir -p target/distrib/velopack/releases | |
| vpk download github \ | |
| --repoUrl "https://github.com/${{ github.repository }}" \ | |
| --token "$GH_TOKEN" \ | |
| --outputDir target/distrib/velopack/releases \ | |
| --channel "$CHANNEL" | |
| - name: Pack with Velopack | |
| if: steps.velopack-params.outputs.supported == 'true' | |
| shell: bash | |
| env: | |
| # `build-local-artifacts` runs with the release tag (e.g. | |
| # `v0.3.0-rc.2`) on `GITHUB_REF_NAME`; vpk wants a bare | |
| # semver, so strip the `v` prefix to match what cargo-dist's | |
| # `--tag=` consumes and what `velopack_bridge.rs` compares | |
| # against at runtime. | |
| GITHUB_REF_NAME: ${{ github.ref_name }} | |
| CHANNEL: ${{ steps.velopack-params.outputs.channel }} | |
| MAIN_EXE: ${{ steps.velopack-params.outputs.mainExe }} | |
| BUNDLE_ID: ${{ steps.velopack-params.outputs.bundleId }} | |
| run: | | |
| packVersion="${GITHUB_REF_NAME#v}" | |
| echo "Packing velopack release with version $packVersion (channel $CHANNEL)" | |
| # Pack id renamed `codescope-rs` → `codescope` in cutover-3 | |
| # (ADR-0022). This strands the auto-update lineage of any | |
| # `codescope-rs`-pack-id install exactly once; users | |
| # reinstall from the first post-cutover release. | |
| args=( | |
| pack | |
| --packId codescope | |
| --packVersion "$packVersion" | |
| --packDir target/distrib/velopack/publish | |
| --mainExe "$MAIN_EXE" | |
| --packTitle CodeScope | |
| --packAuthors maui1911 | |
| --channel "$CHANNEL" | |
| --outputDir target/distrib/velopack/releases | |
| ) | |
| # Per-platform extras: | |
| # * Windows: ship the bundled `.ico` as the installer icon. | |
| # macOS/Linux Velopack accepts PNG, but the repo only has a | |
| # `.ico` today (the C# build ships the same single icon). | |
| # Skipping `--icon` on those platforms is the patient- | |
| # iteration trade-off — Velopack falls back to a generic | |
| # bundle icon; a follow-up will add a PNG and the | |
| # `--icon` flag here once that lands. | |
| # * macOS: `--bundleId` is required for the `.app` wrapper | |
| # Velopack generates. Reverse-DNS under | |
| # `com.maui1911.codescope-rs`. | |
| # * Code signing: unsigned everywhere for now. macOS will | |
| # prompt Gatekeeper on first launch; Velopack's apply path | |
| # still works because the .app stays on the user's box | |
| # after the prompt is dismissed. Documented follow-up. | |
| if [ "$RUNNER_OS" = "Windows" ]; then | |
| args+=(--icon assets/codescope.ico) | |
| fi | |
| if [ -n "$BUNDLE_ID" ]; then | |
| args+=(--bundleId "$BUNDLE_ID") | |
| fi | |
| vpk "${args[@]}" | |
| echo "Velopack outputs:" | |
| ls -la target/distrib/velopack/releases | |
| - name: Collect Velopack upload paths | |
| # Append the velopack release files (`releases.<channel>.json`, | |
| # `RELEASES-<channel>`, *.nupkg, installer / bundle) to the | |
| # upload-artifact path list so the host job picks them up and | |
| # `gh release create` attaches them alongside the cargo-dist | |
| # archives. | |
| if: steps.velopack-params.outputs.supported == 'true' | |
| id: velopack-paths | |
| shell: bash | |
| run: | | |
| # Emit workspace-relative paths so they round-trip through | |
| # upload-artifact the same way the cargo-dist outputs do | |
| # (see the matching comment in the Post-build step above). | |
| echo "paths<<EOF" >> "$GITHUB_OUTPUT" | |
| find target/distrib/velopack/releases -maxdepth 1 -type f \ | |
| >> "$GITHUB_OUTPUT" | |
| echo "EOF" >> "$GITHUB_OUTPUT" | |
| echo "Velopack upload paths:" | |
| find target/distrib/velopack/releases -maxdepth 1 -type f | |
| - name: "Upload artifacts" | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: artifacts-build-local-${{ join(matrix.targets, '_') }} | |
| path: | | |
| ${{ steps.cargo-dist.outputs.paths }} | |
| ${{ env.BUILD_MANIFEST_NAME }} | |
| ${{ steps.velopack-paths.outputs.paths }} | |
| # Build and package all the platform-agnostic(ish) things | |
| build-global-artifacts: | |
| needs: | |
| - plan | |
| - build-local-artifacts | |
| runs-on: "ubuntu-22.04" | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| submodules: recursive | |
| - name: Install cached dist | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: cargo-dist-cache | |
| path: ~/.cargo/bin/ | |
| - run: chmod +x ~/.cargo/bin/dist | |
| # Get all the local artifacts for the global tasks to use (for | |
| # e.g. checksums). Extract to workspace root — uploaded entries | |
| # already carry their `target/distrib/...` paths, so this | |
| # restores the original layout. | |
| - name: Fetch local artifacts | |
| uses: actions/download-artifact@v7 | |
| with: | |
| pattern: artifacts-* | |
| path: . | |
| merge-multiple: true | |
| - id: cargo-dist | |
| shell: bash | |
| run: | | |
| dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json | |
| echo "dist ran successfully" | |
| # Parse out what we just built and upload it to scratch | |
| # storage. `upload_files` in the dist manifest holds | |
| # ABSOLUTE paths (`/home/runner/.../target/distrib/foo`). | |
| # Strip the runner-specific prefix back to `target/distrib/` | |
| # so each upload entry lands at its workspace-relative path. | |
| # `tr` normalizes `\` → `/` defensively even though this | |
| # job only runs on ubuntu — keeps the pipeline identical | |
| # to the build-local variant for future-proofing. | |
| echo "paths<<EOF" >> "$GITHUB_OUTPUT" | |
| jq --raw-output ".upload_files[]" dist-manifest.json \ | |
| | tr '\\' '/' \ | |
| | sed 's|^.*/target/|target/|' \ | |
| >> "$GITHUB_OUTPUT" | |
| echo "EOF" >> "$GITHUB_OUTPUT" | |
| echo "Upload paths (post-rewrite):" | |
| jq --raw-output ".upload_files[]" dist-manifest.json \ | |
| | tr '\\' '/' \ | |
| | sed 's|^.*/target/|target/|' | |
| cp dist-manifest.json "$BUILD_MANIFEST_NAME" | |
| - name: "Upload artifacts" | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: artifacts-build-global | |
| path: | | |
| ${{ steps.cargo-dist.outputs.paths }} | |
| ${{ env.BUILD_MANIFEST_NAME }} | |
| # Determines if we should publish/announce | |
| host: | |
| needs: | |
| - plan | |
| - build-local-artifacts | |
| - build-global-artifacts | |
| # Only run if we're "publishing", and only if plan, local and global didn't fail (skipped is fine) | |
| if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| runs-on: "ubuntu-22.04" | |
| outputs: | |
| val: ${{ steps.host.outputs.manifest }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| submodules: recursive | |
| - name: Install cached dist | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: cargo-dist-cache | |
| path: ~/.cargo/bin/ | |
| - run: chmod +x ~/.cargo/bin/dist | |
| # Fetch artifacts from scratch-storage. Extract to workspace | |
| # root so the `target/...` paths embedded in each upload land at | |
| # their natural location, where `dist host` finds them. | |
| - name: Fetch artifacts | |
| uses: actions/download-artifact@v7 | |
| with: | |
| pattern: artifacts-* | |
| path: . | |
| merge-multiple: true | |
| - id: host | |
| shell: bash | |
| run: | | |
| dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json | |
| echo "artifacts uploaded and released successfully" | |
| cat dist-manifest.json | |
| echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" | |
| - name: "Upload dist-manifest.json" | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| # Overwrite the previous copy | |
| name: artifacts-dist-manifest | |
| path: dist-manifest.json | |
| # Create a GitHub Release while uploading all files to it | |
| - name: "Download GitHub Artifacts" | |
| uses: actions/download-artifact@v7 | |
| with: | |
| pattern: artifacts-* | |
| path: artifacts | |
| merge-multiple: true | |
| - name: Cleanup | |
| run: | | |
| # Uploaded artifacts preserve their workspace-relative paths. | |
| # Every upload step (plan / build-local / build-global) | |
| # stores entries under `target/...`, so after merge-multiple | |
| # they land under `artifacts/target/...`. Flatten every | |
| # regular file in `artifacts/` down to `artifacts/<basename>` | |
| # so `gh release create artifacts/*` (which doesn't recurse | |
| # into directories) sees the release files. | |
| echo "Before flatten:" | |
| find artifacts -type f | sort | |
| find artifacts -mindepth 2 -type f -exec mv -t artifacts/ {} + | |
| find artifacts -mindepth 1 -type d -empty -delete | |
| # Remove the granular manifests | |
| rm -f artifacts/*-dist-manifest.json | |
| echo "After flatten:" | |
| find artifacts -type f | sort | |
| - name: Create GitHub Release | |
| env: | |
| PRERELEASE_FLAG: "${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease && '--prerelease' || '' }}" | |
| ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" | |
| ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" | |
| RELEASE_COMMIT: "${{ github.sha }}" | |
| run: | | |
| # Debug: list everything that will go up as a release asset. | |
| echo "Artifacts to upload:" | |
| ls -la artifacts/ | |
| # Write and read notes from a file to avoid quoting breaking things. | |
| printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" | |
| gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* | |
| announce: | |
| needs: | |
| - plan | |
| - host | |
| # use "always() && ..." to allow us to wait for all publish jobs while | |
| # still allowing individual publish jobs to skip themselves (for prereleases). | |
| # "host" however must run to completion, no skipping allowed! | |
| if: ${{ always() && needs.host.result == 'success' }} | |
| runs-on: "ubuntu-22.04" | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| submodules: recursive |