From 82c8f579b00ac7924cf414d548448802f30d63b4 Mon Sep 17 00:00:00 2001 From: trivernis Date: Thu, 2 Feb 2023 19:35:35 +0100 Subject: [PATCH] Add cargo dist --- .github/workflows/release.yml | 184 ++++++++++++++++++++++++---------- Cargo.toml | 7 ++ 2 files changed, 139 insertions(+), 52 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4432bdf..eb5583f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,70 +1,150 @@ -name: "Build and Release" +# CI that: +# +# * checks for a Git Tag that looks like a release ("v1.2.0") +# * creates a Github Release™️ +# * builds binaries/packages with cargo-dist +# * uploads those packages to the Github Release™️ +# +# Note that the Github Release™️ will be created before the packages, +# so there will be a few minutes where the release has no packages +# and then they will slowly trickle in, possibly failing. To make +# this more pleasant we mark the release as a "draft" until all +# artifacts have been successfully uploaded. This allows you to +# choose what to do with partial successes and avoids spamming +# anyone with notifications before the release is actually ready. +name: Release + +permissions: + contents: write + +# This task will run whenever you push a git tag that looks like +# a version number. We just look for `v` followed by at least one number +# and then whatever. so `v1`, `v1.0.0`, and `v1.0.0-prerelease` all work. +# +# If there's a prerelease-style suffix to the version then the Github Release™️ +# will be marked as a prerelease (handled by taiki-e/create-gh-release-action). +# +# Note that when generating links to uploaded artifacts, cargo-dist will currently +# assume that your git tag is always v{VERSION} where VERSION is the version in +# the published package's Cargo.toml (this is the default behaviour of cargo-release). +# In the future this may be made more robust/configurable. on: push: tags: - - "v*" - workflow_dispatch: + - v[0-9]+.* + +env: + ALL_CARGO_DIST_TARGET_ARGS: --target=x86_64-unknown-linux-gnu --target=x86_64-apple-darwin --target=x86_64-pc-windows-msvc + ALL_CARGO_DIST_INSTALLER_ARGS: --installer=github-shell --installer=github-powershell jobs: - create-release-draft: - name: pre-release + # Create the Github Release™️ so the packages have something to be uploaded to + create-release: runs-on: ubuntu-latest - permissions: - contents: write outputs: - release_upload_url: ${{ steps.create_release.outputs.upload_url }} + tag: ${{ steps.create-gh-release.outputs.computed-prefix }}${{ steps.create-gh-release.outputs.version }} steps: - - uses: actions/checkout@v2 - if: ${{ !env.ACT }} - - - id: create_release - uses: ncipollo/release-action@v1 - if: ${{ !env.ACT }} + - uses: actions/checkout@v3 + - id: create-gh-release + uses: taiki-e/create-gh-release-action@v1 with: draft: true - artifacts: | - LICENSE + # (required) GitHub token for creating GitHub Releases. + token: ${{ secrets.GITHUB_TOKEN }} + - build-release: - needs: create-release-draft + # Build and packages all the things + upload-artifacts: + needs: create-release strategy: - fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + # For these target platforms + include: + - target: x86_64-unknown-linux-gnu + os: ubuntu-20.04 + install-dist: curl --proto '=https' --tlsv1.2 -L -sSf https://github.com/axodotdev/cargo-dist/releases/download/v0.0.2/installer.sh | sh + - target: x86_64-apple-darwin + os: macos-11 + install-dist: curl --proto '=https' --tlsv1.2 -L -sSf https://github.com/axodotdev/cargo-dist/releases/download/v0.0.2/installer.sh | sh + - target: x86_64-pc-windows-msvc + os: windows-2019 + install-dist: irm 'https://github.com/axodotdev/cargo-dist/releases/download/v0.0.2/installer.ps1' | iex runs-on: ${{ matrix.os }} - permissions: - contents: write + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v2 - if: ${{ !env.ACT }} + - uses: actions/checkout@v3 + - name: Install Rust + run: rustup update stable && rustup default stable + - name: Install cargo-dist + run: ${{ matrix.install-dist }} + - name: Run cargo-dist + # This logic is a bit janky because it's trying to be a polyglot between + # powershell and bash since this will run on windows, macos, and linux! + # The two platforms don't agree on how to talk about env vars but they + # do agree on 'cat' and '$()' so we use that to marshal values between commmands. + run: | + # Actually do builds and make zips and whatnot + cargo dist --target=${{ matrix.target }} --output-format=json > dist-manifest.json + echo "dist ran successfully" + cat dist-manifest.json + # Parse out what we just built and upload it to the Github Release™️ + cat dist-manifest.json | jq --raw-output ".releases[].artifacts[].path" > uploads.txt + echo "uploading..." + cat uploads.txt + gh release upload ${{ needs.create-release.outputs.tag }} $(cat uploads.txt) + echo "uploaded!" - - name: Cache build data - if: ${{ !env.ACT }} - uses: actions/cache@v2 - with: - path: | - target - ~/.cargo/ - key: ${{ runner.os }}-cargo-${{ hashFiles('Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cargo- - - name: Build - run: cargo build --release + # Compute and upload the manifest for everything + upload-manifest: + needs: create-release + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v3 + - name: Install Rust + run: rustup update stable && rustup default stable + - name: Install cargo-dist + run: curl --proto '=https' --tlsv1.2 -L -sSf https://github.com/axodotdev/cargo-dist/releases/download/v0.0.2/installer.sh | sh + - name: Run cargo-dist manifest + run: | + # Generate a manifest describing everything + cargo dist manifest --no-local-paths --output-format=json $ALL_CARGO_DIST_TARGET_ARGS $ALL_CARGO_DIST_INSTALLER_ARGS > dist-manifest.json + echo "dist manifest ran successfully" + cat dist-manifest.json + # Upload the manifest to the Github Release™️ + gh release upload ${{ needs.create-release.outputs.tag }} dist-manifest.json + echo "uploaded manifest!" + # Edit the Github Release™️ title/body to match what cargo-dist thinks it should be + CHANGELOG_TITLE=$(cat dist-manifest.json | jq --raw-output ".releases[].changelog_title") + cat dist-manifest.json | jq --raw-output ".releases[].changelog_body" > new_dist_changelog.md + gh release edit ${{ needs.create-release.outputs.tag }} --title="$CHANGELOG_TITLE" --notes-file=new_dist_changelog.md + echo "updated release notes!" + - name: Run cargo-dist --installer=... + run: | + # Run cargo dist with --no-builds to get agnostic artifacts like installers + cargo dist --output-format=json --no-builds $ALL_CARGO_DIST_INSTALLER_ARGS > dist-manifest.json + echo "dist ran successfully" + cat dist-manifest.json + # Grab the installers that were generated and upload them. + # This filter is working around the fact that --no-builds is kinds hacky + # and still makes/reports malformed zips that we don't want to upload. + cat dist-manifest.json | jq --raw-output '.releases[].artifacts[] | select(.kind == "installer") | .path' > uploads.txt + echo "uploading..." + cat uploads.txt + gh release upload ${{ needs.create-release.outputs.tag }} $(cat uploads.txt) + echo "uploaded installers!" - - uses: vimtor/action-zip@v1 - with: - files: | - target/release/nenv - target/release/nenv.exe - dest: nenv-${{ runner.os }}.zip + # Mark the Github Release™️ as a non-draft now that everything has succeeded! + publish-release: + needs: [create-release, upload-artifacts, upload-manifest] + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v3 + - name: mark release as non-draft + run: | + gh release edit ${{ needs.create-release.outputs.tag }} --draft=false - - name: Upload Release Asset - id: upload-release-asset - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ needs.create-release-draft.outputs.release_upload_url }} - asset_path: ./nenv-${{ runner.os }}.zip - asset_name: nenv-${{ runner.os }}.zip - asset_content_type: application/zip \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index a615a52..73efb36 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,3 +44,10 @@ tracing-subscriber = { version = "0.3.16", features = ["env-filter"] } xkcd_unreachable = "0.1.1" zip = "0.6.3" +# generated by 'cargo dist init' +[profile.dist] +inherits = "release" +debug = true +split-debuginfo = "packed" + +