From dbf390c086129c63bc20db5033451c80ee6d3409 Mon Sep 17 00:00:00 2001 From: furiosa Date: Wed, 7 Jan 2026 11:58:15 -0800 Subject: [PATCH 1/4] Add cosign binary signing to GitHub Actions release workflow Uses sigstore/cosign-installer@v3 with keyless signing via GitHub OIDC. Both upload-mac-universal-bin and upload-linux-bin jobs now: - Install cosign - Sign release artifacts with cosign sign-blob - Upload .sig signature files alongside tarballs Artifacts signed: - pks-mac.tar.gz (macOS universal) - x86_64-unknown-linux-gnu.tar.gz - aarch64-unknown-linux-gnu.tar.gz --- .github/workflows/ci.yml | 44 ++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 213d4cc..b8776f5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -102,12 +102,19 @@ jobs: needs: release runs-on: macos-latest if: ${{needs.release.outputs.new_version}} + permissions: + contents: write + id-token: write steps: - uses: actions/checkout@v3 + + - name: Install cosign + uses: sigstore/cosign-installer@v3 + - name: Build run: cargo build --release --target aarch64-apple-darwin --target x86_64-apple-darwin - - name: Upload mac universal binary + - name: Create mac universal binary run: | # This combines the intel and m1 binaries into a single binary lipo -create -output target/pks target/aarch64-apple-darwin/release/pks target/x86_64-apple-darwin/release/pks @@ -115,9 +122,13 @@ jobs: # Creates artifact for homebrew. -C means run from `target` directory tar -czf target/pks-mac.tar.gz -C target pks - # This tarball is a binary that is executable - gh release upload $NEW_VERSION target/pks-mac.tar.gz + - name: Sign mac binary with cosign + run: | + cosign sign-blob --yes --output-signature target/pks-mac.tar.gz.sig target/pks-mac.tar.gz + - name: Upload mac universal binary and signature + run: | + gh release upload $NEW_VERSION target/pks-mac.tar.gz target/pks-mac.tar.gz.sig env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} NEW_VERSION: ${{ needs.release.outputs.new_version }} @@ -126,21 +137,38 @@ jobs: needs: release if: ${{needs.release.outputs.new_version}} runs-on: ubuntu-latest + permissions: + contents: write + id-token: write steps: - uses: actions/checkout@v4 + + - name: Install cosign + uses: sigstore/cosign-installer@v3 + - name: Update local toolchain run: | cargo install cross + - name: Build linux binaries run: | cross build --release --target x86_64-unknown-linux-gnu cross build --release --target aarch64-unknown-linux-gnu - - name: Upload linux binaries + + - name: Create linux binary tarballs + run: | + tar -czf target/x86_64-unknown-linux-gnu.tar.gz -C target/x86_64-unknown-linux-gnu/release pks + tar -czf target/aarch64-unknown-linux-gnu.tar.gz -C target/aarch64-unknown-linux-gnu/release pks + + - name: Sign linux binaries with cosign + run: | + cosign sign-blob --yes --output-signature target/x86_64-unknown-linux-gnu.tar.gz.sig target/x86_64-unknown-linux-gnu.tar.gz + cosign sign-blob --yes --output-signature target/aarch64-unknown-linux-gnu.tar.gz.sig target/aarch64-unknown-linux-gnu.tar.gz + + - name: Upload linux binaries and signatures run: | - tar -czf target/x86_64-unknown-linux-gnu.tar.gz -C target/x86_64-unknown-linux-gnu/release pks - tar -czf target/aarch64-unknown-linux-gnu.tar.gz -C target/aarch64-unknown-linux-gnu/release pks - gh release upload $NEW_VERSION target/x86_64-unknown-linux-gnu.tar.gz - gh release upload $NEW_VERSION target/aarch64-unknown-linux-gnu.tar.gz + gh release upload $NEW_VERSION target/x86_64-unknown-linux-gnu.tar.gz target/x86_64-unknown-linux-gnu.tar.gz.sig + gh release upload $NEW_VERSION target/aarch64-unknown-linux-gnu.tar.gz target/aarch64-unknown-linux-gnu.tar.gz.sig env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} NEW_VERSION: ${{ needs.release.outputs.new_version }} From fe5ad1185ca1c24bb9fc1601590f06ccffbff1a3 Mon Sep 17 00:00:00 2001 From: nux Date: Wed, 7 Jan 2026 12:00:32 -0800 Subject: [PATCH 2/4] Add cargo-audit security scanning as release gate Integrates cargo-audit into the CI workflow as a required check that must pass before releases can proceed. Also updates the standalone audit.yml to use modern cargo-audit tooling instead of the deprecated actions-rs/audit-check action. - Add security-audit job to ci.yml - Make release job depend on security-audit passing - Update audit.yml to use cargo-audit directly with actions/checkout@v4 --- .github/workflows/audit.yml | 13 ++++++++----- .github/workflows/ci.yml | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index 74460f7..6a3cf90 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -2,7 +2,7 @@ name: Security audit on: schedule: - - cron: 0 0 * * 1 + - cron: '0 0 * * 1' push: paths: - '**/Cargo.toml' @@ -13,7 +13,10 @@ jobs: audit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions-rs/audit-check@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/checkout@v4 + + - name: Install cargo-audit + run: cargo install cargo-audit + + - name: Run security audit + run: cargo audit diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 213d4cc..0f11eab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,12 +53,26 @@ jobs: - name: Run cargo clippy run: cargo clippy --all-targets --all-features + security-audit: + name: Security Audit + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: Install cargo-audit + run: cargo install cargo-audit + + - name: Run security audit + run: cargo audit + release: runs-on: macos-latest needs: - test - lints - check + - security-audit outputs: new_version: ${{ steps.check_for_version_changes.outputs.new_version }} changed: ${{ steps.check_for_version_changes.outputs.changed }} From 9d9b3fcefbd8652797093ec1ba0efe81a758d6a1 Mon Sep 17 00:00:00 2001 From: rictus Date: Wed, 7 Jan 2026 12:00:43 -0800 Subject: [PATCH 3/4] Add release-plz automation for changelog and version management - Add release-plz.yml workflow that creates release PRs with version bumps and changelog updates from conventional commits - Add release-binaries.yml workflow triggered on release publish to build and upload macOS/Linux binaries and DotSlash files - Update ci.yml to remove manual release logic (now handled by release-plz) and upgrade checkout actions to v4 - Add release-plz.toml config for changelog generation without crates.io publishing --- .github/workflows/ci.yml | 121 +------------------------ .github/workflows/release-binaries.yml | 68 ++++++++++++++ .github/workflows/release-plz.yml | 28 ++++++ release-plz.toml | 19 ++++ 4 files changed, 118 insertions(+), 118 deletions(-) create mode 100644 .github/workflows/release-binaries.yml create mode 100644 .github/workflows/release-plz.yml create mode 100644 release-plz.toml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 213d4cc..d0e284d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Run cargo check run: cargo check @@ -32,7 +32,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Run cargo test with backtrace run: cargo test -- --nocapture @@ -45,125 +45,10 @@ jobs: RUSTFLAGS: "-Dwarnings" steps: - name: Checkout sources - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Run cargo fmt run: cargo fmt --all -- --check - name: Run cargo clippy run: cargo clippy --all-targets --all-features - - release: - runs-on: macos-latest - needs: - - test - - lints - - check - outputs: - new_version: ${{ steps.check_for_version_changes.outputs.new_version }} - changed: ${{ steps.check_for_version_changes.outputs.changed }} - if: github.ref == 'refs/heads/main' - steps: - - uses: actions/checkout@v3 - with: - # https://stackoverflow.com/questions/65944700/how-to-run-git-diff-in-github-actions - # TLDR – By default this action fetches no history. - # We need a bit of history to be able to check if we've recently updated the version in Cargo.toml - fetch-depth: 2 - - name: Toolchain info - run: | - cargo --version --verbose - rustc --version - cargo clippy --version - - name: Build - run: cargo build --release --target aarch64-apple-darwin --target x86_64-apple-darwin - - name: Check for version changes in Cargo.toml - id: check_for_version_changes - run: | - # When there are no changes, VERSION_CHANGES will be empty - # Without the echo, this command would exit with a 1, causing the GitHub Action to fail - # Instead, we want it to succeed, but just evaluate `changed=false` in the other branch of the conditional - VERSION_CHANGES=$(git diff HEAD~1 HEAD Cargo.toml | grep "\+version" || echo "") - if [[ -n $VERSION_CHANGES ]]; then - NEW_VERSION=$(echo $VERSION_CHANGES | awk -F'"' '{print $2}') - echo "changed=true" >> $GITHUB_OUTPUT - echo "new_version=v$NEW_VERSION" >> $GITHUB_OUTPUT - else - echo "changed=false" >> $GITHUB_OUTPUT - fi - - - name: Create GitHub Release if current commit has updated the version in Cargo.toml - if: steps.check_for_version_changes.outputs.changed == 'true' - run: | - gh release create ${{steps.check_for_version_changes.outputs.new_version}} --target "${{ github.sha }}" --generate-notes - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - upload-mac-universal-bin: - needs: release - runs-on: macos-latest - if: ${{needs.release.outputs.new_version}} - steps: - - uses: actions/checkout@v3 - - name: Build - run: cargo build --release --target aarch64-apple-darwin --target x86_64-apple-darwin - - - name: Upload mac universal binary - run: | - # This combines the intel and m1 binaries into a single binary - lipo -create -output target/pks target/aarch64-apple-darwin/release/pks target/x86_64-apple-darwin/release/pks - - # Creates artifact for homebrew. -C means run from `target` directory - tar -czf target/pks-mac.tar.gz -C target pks - - # This tarball is a binary that is executable - gh release upload $NEW_VERSION target/pks-mac.tar.gz - - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NEW_VERSION: ${{ needs.release.outputs.new_version }} - - upload-linux-bin: - needs: release - if: ${{needs.release.outputs.new_version}} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Update local toolchain - run: | - cargo install cross - - name: Build linux binaries - run: | - cross build --release --target x86_64-unknown-linux-gnu - cross build --release --target aarch64-unknown-linux-gnu - - name: Upload linux binaries - run: | - tar -czf target/x86_64-unknown-linux-gnu.tar.gz -C target/x86_64-unknown-linux-gnu/release pks - tar -czf target/aarch64-unknown-linux-gnu.tar.gz -C target/aarch64-unknown-linux-gnu/release pks - gh release upload $NEW_VERSION target/x86_64-unknown-linux-gnu.tar.gz - gh release upload $NEW_VERSION target/aarch64-unknown-linux-gnu.tar.gz - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NEW_VERSION: ${{ needs.release.outputs.new_version }} - - generate-dotslash-files: - name: Generating and uploading DotSlash files - needs: - - release - - upload-linux-bin - - upload-mac-universal-bin - if: success() && ${{needs.release.outputs.new_version}} - runs-on: ubuntu-latest - - steps: - - uses: facebook/dotslash-publish-release@v1 - # This is necessary because the action uses - # `gh release upload` to publish the generated DotSlash file(s) - # as part of the release. - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - # Additional file that lives in your repo that defines - # how your DotSlash file(s) should be generated. - config: .github/workflows/dotslash-config.json - # Tag for the release to target. - tag: ${{ needs.release.outputs.new_version }} diff --git a/.github/workflows/release-binaries.yml b/.github/workflows/release-binaries.yml new file mode 100644 index 0000000..bb5558d --- /dev/null +++ b/.github/workflows/release-binaries.yml @@ -0,0 +1,68 @@ +name: Release Binaries + +on: + release: + types: [published] + +env: + CARGO_TERM_COLOR: always + +jobs: + upload-mac-universal-bin: + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + + - name: Build macOS binaries + run: cargo build --release --target aarch64-apple-darwin --target x86_64-apple-darwin + + - name: Create universal binary and upload + run: | + # Combine intel and m1 binaries into a single universal binary + lipo -create -output target/pks target/aarch64-apple-darwin/release/pks target/x86_64-apple-darwin/release/pks + + # Create tarball for homebrew + tar -czf target/pks-mac.tar.gz -C target pks + + # Upload to release + gh release upload ${{ github.event.release.tag_name }} target/pks-mac.tar.gz + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + upload-linux-bin: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install cross + run: cargo install cross + + - name: Build linux binaries + run: | + cross build --release --target x86_64-unknown-linux-gnu + cross build --release --target aarch64-unknown-linux-gnu + + - name: Upload linux binaries + run: | + tar -czf target/x86_64-unknown-linux-gnu.tar.gz -C target/x86_64-unknown-linux-gnu/release pks + tar -czf target/aarch64-unknown-linux-gnu.tar.gz -C target/aarch64-unknown-linux-gnu/release pks + gh release upload ${{ github.event.release.tag_name }} target/x86_64-unknown-linux-gnu.tar.gz + gh release upload ${{ github.event.release.tag_name }} target/aarch64-unknown-linux-gnu.tar.gz + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + generate-dotslash-files: + name: Generate DotSlash files + needs: + - upload-linux-bin + - upload-mac-universal-bin + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: facebook/dotslash-publish-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + config: .github/workflows/dotslash-config.json + tag: ${{ github.event.release.tag_name }} diff --git a/.github/workflows/release-plz.yml b/.github/workflows/release-plz.yml new file mode 100644 index 0000000..1d9b5df --- /dev/null +++ b/.github/workflows/release-plz.yml @@ -0,0 +1,28 @@ +name: Release-plz + +permissions: + pull-requests: write + contents: write + +on: + push: + branches: + - main + +jobs: + release-plz: + name: Release-plz + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Run release-plz + uses: release-plz/action@v0.5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/release-plz.toml b/release-plz.toml new file mode 100644 index 0000000..ca5f618 --- /dev/null +++ b/release-plz.toml @@ -0,0 +1,19 @@ +[workspace] +# Don't publish to crates.io - binaries are distributed via GitHub releases +publish = false +# Create GitHub releases when release PR is merged +git_release_enable = true +# Generate changelog from conventional commits +changelog_update = true + +[changelog] +# Use conventional commits to generate changelog +commit_parsers = [ + { message = "^feat", group = "Features" }, + { message = "^fix", group = "Bug Fixes" }, + { message = "^docs", group = "Documentation" }, + { message = "^perf", group = "Performance" }, + { message = "^refactor", group = "Refactoring" }, + { message = "^test", group = "Testing" }, + { message = "^chore", group = "Miscellaneous" }, +] From 9fc50cbfc8c14eca778234ad428ad053a2df0fb0 Mon Sep 17 00:00:00 2001 From: slit Date: Wed, 7 Jan 2026 12:01:37 -0800 Subject: [PATCH 4/4] Initialize cargo-dist for automated binary distribution Configure cross-platform release builds targeting x86_64/aarch64 for Linux and macOS, with shell and PowerShell installers. GitHub Actions workflow will trigger on version tags. --- .github/workflows/release.yml | 296 ++++++++++++++++++++++++++++++++++ Cargo.toml | 5 + dist-workspace.toml | 17 ++ 3 files changed, 318 insertions(+) create mode 100644 .github/workflows/release.yml create mode 100644 dist-workspace.toml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..3c59af5 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,296 @@ +# 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: + pull_request: + push: + tags: + - '**[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: ${{ !github.event.pull_request && github.ref_name || '' }} + tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + publishing: ${{ !github.event.pull_request }} + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + submodules: recursive + - 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.30.3/cargo-dist-installer.sh | sh" + - name: Cache dist + uses: actions/upload-artifact@v4 + 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 + run: | + dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --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@v4 + 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 }} + 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@v4 + 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 + - name: Fetch local artifacts + uses: actions/download-artifact@v4 + with: + pattern: artifacts-* + path: target/distrib/ + merge-multiple: true + - name: Install dependencies + run: | + ${{ matrix.packages_install }} + - name: Build artifacts + run: | + # 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 + echo "paths<> "$GITHUB_OUTPUT" + dist print-upload-files-from-manifest --manifest dist-manifest.json >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + + cp dist-manifest.json "$BUILD_MANIFEST_NAME" + - name: "Upload artifacts" + uses: actions/upload-artifact@v4 + with: + name: artifacts-build-local-${{ join(matrix.targets, '_') }} + path: | + ${{ steps.cargo-dist.outputs.paths }} + ${{ env.BUILD_MANIFEST_NAME }} + + # 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@v4 + with: + persist-credentials: false + submodules: recursive + - name: Install cached dist + uses: actions/download-artifact@v4 + 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) + - name: Fetch local artifacts + uses: actions/download-artifact@v4 + with: + pattern: artifacts-* + path: target/distrib/ + 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 + echo "paths<> "$GITHUB_OUTPUT" + jq --raw-output ".upload_files[]" dist-manifest.json >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + + cp dist-manifest.json "$BUILD_MANIFEST_NAME" + - name: "Upload artifacts" + uses: actions/upload-artifact@v4 + 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@v4 + with: + persist-credentials: false + submodules: recursive + - name: Install cached dist + uses: actions/download-artifact@v4 + with: + name: cargo-dist-cache + path: ~/.cargo/bin/ + - run: chmod +x ~/.cargo/bin/dist + # Fetch artifacts from scratch-storage + - name: Fetch artifacts + uses: actions/download-artifact@v4 + with: + pattern: artifacts-* + path: target/distrib/ + 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@v4 + 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@v4 + with: + pattern: artifacts-* + path: artifacts + merge-multiple: true + - name: Cleanup + run: | + # Remove the granular manifests + rm -f artifacts/*-dist-manifest.json + - 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: | + # Write and read notes from a file to avoid quoting breaking things + echo "$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@v4 + with: + persist-credentials: false + submodules: recursive diff --git a/Cargo.toml b/Cargo.toml index 666ac5f..efb3795 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,11 @@ repository = "https://github.com/rubyatscale/pks" [profile.dev] debug = true +# The profile that 'dist' will build with +[profile.dist] +inherits = "release" +lto = "thin" + [[bin]] name = "pks" path = "src/main.rs" diff --git a/dist-workspace.toml b/dist-workspace.toml new file mode 100644 index 0000000..f54d589 --- /dev/null +++ b/dist-workspace.toml @@ -0,0 +1,17 @@ +[workspace] +members = ["cargo:."] + +# Config for 'dist' +[dist] +# The preferred dist version to use in CI (Cargo.toml SemVer syntax) +cargo-dist-version = "0.30.3" +# CI backends to support +ci = "github" +# The installers to generate for each app +installers = ["shell", "powershell"] +# Target platforms to build apps for (Rust target-triple syntax) +targets = ["aarch64-apple-darwin", "aarch64-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu", "x86_64-pc-windows-msvc"] +# Path that installers should place binaries in +install-path = "CARGO_HOME" +# Whether to install an updater program +install-updater = false