chore(rs): bump version to 0.3.0-rc.4 (#194) #12
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 Rust release pipeline off the critical | |
| # path for day-to-day PRs — `pr-run-mode = "skip"` in | |
| # `codescope-rs/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 `rs-v0.0.2` and `rs-v0.3.0-rc1` match. Copilot | |
| # caught the original regex-style pattern in PR #162 review. | |
| tags: | |
| - 'rs-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 *original* git tag (e.g. `rs-v0.3.0-rc1`) — used as the | |
| # GitHub release tag downstream so the two release pipelines on this | |
| # repo (C# `v*` and Rust `rs-v*`) don't collide. | |
| # `tag-flag` is the *stripped* tag (e.g. `v0.3.0-rc1`) passed to every | |
| # `dist` invocation via `--tag=`. cargo-dist 0.31's `tag-namespace` | |
| # config only controls the workflow filename and the trigger glob; it | |
| # does NOT strip the namespace before the underlying `axotag` parser | |
| # sees the value. `axotag` then tries to parse `rs-v0.3.0-rc1` as | |
| # `<package-name>-v<version>` (no package called `rs` exists) or as a | |
| # bare semver (fails on the `r`). Stripping `rs-` here side-steps the | |
| # bug — cargo-dist sees a clean `v0.3.0-rc1` and the GitHub release | |
| # below is still tagged `rs-v0.3.0-rc1` because `gh release create` | |
| # uses `needs.plan.outputs.tag` (the un-stripped value). | |
| 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 namespaced + stripped tag values once and reuse them | |
| # across every downstream `dist` call. See the comment on the | |
| # `tag` / `tag-flag` job outputs above for why both are needed. | |
| # 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 }}" | |
| # Strip the `rs-` namespace prefix (matches `tag-namespace` in | |
| # `codescope-rs/dist-workspace.toml`). `${var#prefix}` is a | |
| # POSIX shell parameter expansion that removes the shortest | |
| # leading match — exactly what we want. | |
| STRIPPED_TAG="${FULL_TAG#rs-}" | |
| echo "tag=${FULL_TAG}" >> "$GITHUB_OUTPUT" | |
| echo "tag-flag=--tag=${STRIPPED_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 | |
| # dist-workspace.toml and Cargo.toml live in codescope-rs/, so all | |
| # `dist` invocations run from that subdir. Subsequent jobs extract | |
| # artifacts at the workspace root, so each upload `path:` carries its | |
| # final workspace-relative location (e.g. `codescope-rs/target/...`) | |
| # — keeps the artifact ZIPs round-trip-correct. | |
| # | |
| # Write the plan manifest into the working directory (codescope-rs/), | |
| # 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. | |
| working-directory: codescope-rs | |
| shell: bash | |
| run: | | |
| if [ -z "${{ github.event.pull_request }}" ]; then | |
| # `dist host --steps=create` needs the *stripped* tag (see | |
| # tag-flag rationale on the job outputs above). | |
| 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: codescope-rs/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 }} | |
| # Path is relative to the step's working-directory (codescope-rs) for | |
| # shell use, then re-prefixed below for the upload-artifact `path:` | |
| # (which resolves from $GITHUB_WORKSPACE). | |
| 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 `codescope-rs/target/distrib/...` already — pointing | |
| # the download at the workspace root restores the original layout (using | |
| # `codescope-rs/target/distrib/` here would nest it as | |
| # `codescope-rs/target/distrib/codescope-rs/target/distrib/...`). | |
| - 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 | |
| working-directory: codescope-rs | |
| shell: bash | |
| run: | | |
| # Pin the version slug to the stripped 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 `rs-v*` tag, even though the workflow | |
| # itself was triggered by one. `build.rs` consumes | |
| # `CODESCOPE_VERSION` as an override; strip the leading | |
| # `rs-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#rs-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 | |
| working-directory: codescope-rs | |
| 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\codescope-rs\target\distrib\foo.msi` | |
| # on Windows, `/home/runner/.../codescope-rs/target/distrib/foo.tar.xz` | |
| # on Linux/macOS), not workspace-relative ones. The previous fix | |
| # here was `sed 's|^|codescope-rs/|'`, which glued the prefix onto | |
| # already-absolute paths and produced nonsense like | |
| # `codescope-rs/D:\a\...`. upload-artifact then silently warned the | |
| # bogus paths away (`if-no-files-found: warn`) and the only file | |
| # that actually shipped to the release was the dist-manifest. | |
| # | |
| # Normalize backslashes → forward slashes first (Windows paths), | |
| # then strip everything up to and including `codescope-rs/` and | |
| # re-prepend it. End result: `codescope-rs/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|^.*/codescope-rs/|codescope-rs/|' \ | |
| >> "$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|^.*/codescope-rs/|codescope-rs/|' | |
| cp dist-manifest.json "$BUILD_MANIFEST_NAME" | |
| # --------------------------------------------------------------- | |
| # Velopack packaging — Windows only for now. | |
| # | |
| # The Rust velopack-rs bridge (`codescope-rs/src/velopack_bridge.rs`) | |
| # pins `CHANNEL = "win"` and only the Windows install flow is | |
| # exercised in the AppShell today. macOS + Linux velopack packaging | |
| # is a documented follow-up; tar.xz archives from cargo-dist still | |
| # ship for those platforms via the rest of this matrix entry. | |
| # | |
| # The steps below produce Velopack's canonical feed asset | |
| # `releases.win.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 Velopack setup installer | |
| # (`*-Setup.exe`), all under `codescope-rs/target/distrib/velopack/`. | |
| # Every file is threaded through the same upload-artifact path used | |
| # for the MSI + zip. The steps no-op on macOS/Linux jobs via the | |
| # `runner.os` gate. | |
| # --------------------------------------------------------------- | |
| - name: Setup .NET (for vpk) | |
| if: runner.os == 'Windows' | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '8.0.x' | |
| - name: Install vpk | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: dotnet tool install -g vpk | |
| - name: Stage Velopack publish dir | |
| # cargo-dist already built `codescope-rs.exe` under | |
| # `target/<triple>/release/`. vpk wants a flat publish dir that | |
| # contains the main exe plus any side-by-side files. The Rust | |
| # build is statically linked (no runtime DLLs to ship), so just | |
| # the .exe is enough — but we also copy any sibling .dll cargo | |
| # emits so a future dynamically-linked sidecar gets picked up | |
| # automatically. | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| working-directory: codescope-rs | |
| run: | | |
| $publish = "target/distrib/velopack/publish" | |
| New-Item -ItemType Directory -Force -Path $publish | Out-Null | |
| # cargo-dist 0.31 builds Windows binaries with `--profile dist`, | |
| # which lands the exe at `target/<triple>/dist/codescope-rs.exe` | |
| # (NOT the default `release/` profile dir). Older cargo-dist | |
| # versions used `release/`. Glob both so a future profile | |
| # change doesn't break this step. | |
| Write-Host "Searching target/ for codescope-rs.exe..." | |
| Get-ChildItem -Path "target" -Recurse -Filter "codescope-rs.exe" -ErrorAction SilentlyContinue ` | |
| | ForEach-Object { Write-Host " found: $($_.FullName)" } | |
| $exe = Get-ChildItem -Path "target" -Recurse -Filter "codescope-rs.exe" -ErrorAction SilentlyContinue ` | |
| | Where-Object { $_.FullName -like "*windows*" -and ($_.FullName -like "*\dist\*" -or $_.FullName -like "*\release\*") } ` | |
| | Select-Object -First 1 | |
| if (-not $exe) { | |
| throw "Could not find a release build of codescope-rs.exe under target/<windows triple>/<dist|release>/" | |
| } | |
| $src = $exe.DirectoryName | |
| Write-Host "Staging velopack publish from $src" | |
| Copy-Item -Path $exe.FullName -Destination $publish -Force | |
| # Bring along any side-by-side .dll files cargo emits next to | |
| # the exe. Today there are none, but this future-proofs us | |
| # against e.g. adding a dynamically-linked sidecar. | |
| Get-ChildItem -Path $src -Filter "*.dll" -ErrorAction SilentlyContinue ` | |
| | Copy-Item -Destination $publish -Force | |
| Get-ChildItem $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 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: runner.os == 'Windows' | |
| continue-on-error: true | |
| shell: pwsh | |
| working-directory: codescope-rs | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| New-Item -ItemType Directory -Force -Path target/distrib/velopack/releases | Out-Null | |
| vpk download github ` | |
| --repoUrl "https://github.com/${{ github.repository }}" ` | |
| --token "$env:GH_TOKEN" ` | |
| --outputDir target/distrib/velopack/releases ` | |
| --channel win | |
| - name: Pack with Velopack | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| working-directory: codescope-rs | |
| env: | |
| # `build-local-artifacts` runs with the namespaced tag | |
| # (e.g. `rs-v0.3.0-rc.2`) on `GITHUB_REF_NAME`; vpk wants a | |
| # bare semver, so strip the `rs-v` prefix to match what | |
| # cargo-dist's `--tag=` peels off and what `velopack_bridge.rs` | |
| # compares against at runtime. | |
| GITHUB_REF_NAME: ${{ github.ref_name }} | |
| run: | | |
| $fullTag = $env:GITHUB_REF_NAME | |
| $packVersion = $fullTag -replace '^rs-v','' | |
| Write-Host "Packing velopack release with version $packVersion" | |
| # Flags mirror the C# `.github/workflows/release.yml` velopack | |
| # step (see `vpk pack` block there), with these intentional | |
| # divergences: | |
| # * `--packId codescope-rs` (the Rust port has its own | |
| # application identity — the C# build uses `CodeScope`). | |
| # `velopack_bridge.rs` doesn't pin a packId at runtime; | |
| # vpk's GithubSource matches on channel + repo, so the id | |
| # can differ between the two builds without colliding. | |
| # * No `--splashImage` — the Rust port doesn't ship a splash | |
| # asset (only the icon under `codescope-rs/assets/`). | |
| vpk pack ` | |
| --packId codescope-rs ` | |
| --packVersion $packVersion ` | |
| --packDir target/distrib/velopack/publish ` | |
| --mainExe codescope-rs.exe ` | |
| --packTitle CodeScope ` | |
| --packAuthors maui1911 ` | |
| --icon assets/codescope.ico ` | |
| --channel win ` | |
| --outputDir target/distrib/velopack/releases | |
| Write-Host "Velopack outputs:" | |
| Get-ChildItem target/distrib/velopack/releases | |
| - name: Collect Velopack upload paths | |
| # Append the velopack release files (RELEASES-win, *.nupkg, the | |
| # installer setup .exe) to the upload-artifact path list so the | |
| # host job picks them up and `gh release create` attaches them | |
| # alongside the MSI + zip. | |
| if: runner.os == 'Windows' | |
| id: velopack-paths | |
| shell: bash | |
| working-directory: codescope-rs | |
| 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 \ | |
| | sed 's|^|codescope-rs/|' \ | |
| >> "$GITHUB_OUTPUT" | |
| echo "EOF" >> "$GITHUB_OUTPUT" | |
| echo "Velopack upload paths:" | |
| find target/distrib/velopack/releases -maxdepth 1 -type f \ | |
| | sed 's|^|codescope-rs/|' | |
| - name: "Upload artifacts" | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: artifacts-build-local-${{ join(matrix.targets, '_') }} | |
| path: | | |
| ${{ steps.cargo-dist.outputs.paths }} | |
| codescope-rs/${{ 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 `codescope-rs/target/distrib/...` prefix, so this restores the | |
| # original layout without doubling the prefix. | |
| - name: Fetch local artifacts | |
| uses: actions/download-artifact@v7 | |
| with: | |
| pattern: artifacts-* | |
| path: . | |
| merge-multiple: true | |
| - id: cargo-dist | |
| shell: bash | |
| working-directory: codescope-rs | |
| 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/.../codescope-rs/target/distrib/foo`); the previous | |
| # `sed 's|^|codescope-rs/|'` glued a prefix onto already-absolute | |
| # paths and silently broke the upload — see the matching comment | |
| # in build-local-artifacts. | |
| # | |
| # Strip the runner-specific prefix back to `codescope-rs/` so each | |
| # upload entry lands at `codescope-rs/target/distrib/<file>`. The | |
| # `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|^.*/codescope-rs/|codescope-rs/|' \ | |
| >> "$GITHUB_OUTPUT" | |
| echo "EOF" >> "$GITHUB_OUTPUT" | |
| echo "Upload paths (post-rewrite):" | |
| jq --raw-output ".upload_files[]" dist-manifest.json \ | |
| | tr '\\' '/' \ | |
| | sed 's|^.*/codescope-rs/|codescope-rs/|' | |
| 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 }} | |
| codescope-rs/${{ 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 | |
| # `codescope-rs/...` prefixes embedded in each upload land at their | |
| # natural path, where `dist host` (running from codescope-rs/) finds them. | |
| - name: Fetch artifacts | |
| uses: actions/download-artifact@v7 | |
| with: | |
| pattern: artifacts-* | |
| path: . | |
| merge-multiple: true | |
| - id: host | |
| shell: bash | |
| working-directory: codescope-rs | |
| 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: codescope-rs/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) now stores | |
| # entries under `codescope-rs/...` (see the matching comments | |
| # there), so after merge-multiple they land under | |
| # `artifacts/codescope-rs/...`. 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 }}" | |
| # Re-attach the `rs-` namespace prefix when rewriting download URLs | |
| # below. Keep this in sync with `tag-namespace` in | |
| # codescope-rs/dist-workspace.toml. | |
| TAG_NAMESPACE: "rs-" | |
| 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. | |
| # cargo-dist builds the announcement body using the STRIPPED tag | |
| # (e.g. `v0.3.0-rc.1`) because we feed it `--tag=v0.3.0-rc.1` after | |
| # peeling the `rs-` namespace prefix (see the `tags` step on the | |
| # `plan` job). But the actual GitHub release tag carries the | |
| # namespace (`rs-v0.3.0-rc.1`), so every download URL in the body | |
| # would 404. Patch the release-asset URLs to include the prefix | |
| # before writing the notes file. | |
| printf '%s' "$ANNOUNCEMENT_BODY" \ | |
| | sed "s|/releases/download/v|/releases/download/${TAG_NAMESPACE}v|g" \ | |
| > "$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 |