mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-04-21 04:58:42 +00:00
Sign our releases (#1347)
* Sign our releases * Use secrets instead of artifacts * And the universal * Apparently we can’t use secrets like that? * Minor fixes to doc * Private key requires untrusted comment * Dogfood one deeper
This commit is contained in:
parent
32beba507b
commit
ee7fcb3210
5 changed files with 88 additions and 14 deletions
16
.github/scripts/ephemeral-gen.sh
vendored
Executable file
16
.github/scripts/ephemeral-gen.sh
vendored
Executable file
|
@ -0,0 +1,16 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
cargo binstall -y rsign2
|
||||||
|
rsign generate -f -W -p minisign.pub -s minisign.key
|
||||||
|
|
||||||
|
cat >> crates/bin/Cargo.toml <<EOF
|
||||||
|
[package.metadata.binstall.signing]
|
||||||
|
algorithm = "minisign"
|
||||||
|
pubkey = "$(tail -n1 minisign.pub)"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
set +x
|
||||||
|
echo "::add-mask::$(tail -n1 minisign.key)"
|
||||||
|
echo "private=$(tail -n1 minisign.key)" >> "$GITHUB_OUTPUT"
|
19
.github/scripts/ephemeral-sign.sh
vendored
Executable file
19
.github/scripts/ephemeral-sign.sh
vendored
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
echo "untrusted comment: rsign encrypted secret key" > minisign.key
|
||||||
|
cat >> minisign.key <<< "$SIGNING_KEY"
|
||||||
|
|
||||||
|
set -x
|
||||||
|
|
||||||
|
cargo binstall -y rsign2
|
||||||
|
|
||||||
|
ts=$(date --utc --iso-8601=seconds)
|
||||||
|
git=$(git rev-parse HEAD)
|
||||||
|
comment="gh=$GITHUB_REPOSITORY git=$git ts=$ts run=$GITHUB_RUN_ID"
|
||||||
|
|
||||||
|
for file in "$@"; do
|
||||||
|
rsign sign -W -s minisign.key -x "$file.sig" -t "$comment" "$file"
|
||||||
|
done
|
||||||
|
|
20
.github/workflows/release-build.yml
vendored
20
.github/workflows/release-build.yml
vendored
|
@ -16,6 +16,10 @@ on:
|
||||||
description: "Set to override default release profile codegen-units settings"
|
description: "Set to override default release profile codegen-units settings"
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
|
secrets:
|
||||||
|
signingkey:
|
||||||
|
description: "Minisign private key. Required when publishing"
|
||||||
|
required: false
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
|
@ -84,6 +88,14 @@ jobs:
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- if: inputs.publish
|
||||||
|
uses: cargo-bins/cargo-binstall@main
|
||||||
|
|
||||||
|
- if: inputs.publish
|
||||||
|
env:
|
||||||
|
SIGNING_KEY: ${{ secrets.signingkey }}
|
||||||
|
run: .github/scripts/ephemeral-sign.sh packages/cargo-binstall-*
|
||||||
|
|
||||||
- if: inputs.publish
|
- if: inputs.publish
|
||||||
name: Upload to release
|
name: Upload to release
|
||||||
uses: svenstaro/upload-release-action@v2
|
uses: svenstaro/upload-release-action@v2
|
||||||
|
@ -140,6 +152,14 @@ jobs:
|
||||||
- run: just repackage-lipo
|
- run: just repackage-lipo
|
||||||
- run: ls -shal packages/
|
- run: ls -shal packages/
|
||||||
|
|
||||||
|
- if: inputs.publish
|
||||||
|
uses: cargo-bins/cargo-binstall@main
|
||||||
|
|
||||||
|
- if: inputs.publish
|
||||||
|
env:
|
||||||
|
SIGNING_KEY: ${{ secrets.signingkey }}
|
||||||
|
run: .github/scripts/ephemeral-sign.sh packages/cargo-binstall-universal-*
|
||||||
|
|
||||||
- if: inputs.publish
|
- if: inputs.publish
|
||||||
name: Upload to release
|
name: Upload to release
|
||||||
uses: svenstaro/upload-release-action@v2
|
uses: svenstaro/upload-release-action@v2
|
||||||
|
|
39
.github/workflows/release.yml
vendored
39
.github/workflows/release.yml
vendored
|
@ -22,8 +22,8 @@ jobs:
|
||||||
event-data: ${{ toJSON(github.event) }}
|
event-data: ${{ toJSON(github.event) }}
|
||||||
extract-notes-under: '### Release notes'
|
extract-notes-under: '### Release notes'
|
||||||
|
|
||||||
tag:
|
libtag:
|
||||||
if: needs.info.outputs.is-release == 'true'
|
if: needs.info.outputs.is-release == 'true' && needs.info.outputs.crate != 'cargo-binstall'
|
||||||
needs: info
|
needs: info
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
@ -35,24 +35,43 @@ jobs:
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
custom_tag: ${{ needs.info.outputs.version }}
|
custom_tag: ${{ needs.info.outputs.version }}
|
||||||
tag_prefix: ${{ needs.info.outputs.crate }}-v
|
tag_prefix: ${{ needs.info.outputs.crate }}-v
|
||||||
- name: Push cli release tag
|
|
||||||
if: needs.info.outputs.crate == 'cargo-binstall'
|
|
||||||
uses: mathieudutour/github-tag-action@v6.1
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
custom_tag: ${{ needs.info.outputs.version }}
|
|
||||||
tag_prefix: v
|
|
||||||
- name: Publish to crates.io
|
- name: Publish to crates.io
|
||||||
run: |
|
run: |
|
||||||
cargo publish -p '${{ needs.info.outputs.crate }}'
|
cargo publish -p '${{ needs.info.outputs.crate }}'
|
||||||
env:
|
env:
|
||||||
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
||||||
|
|
||||||
|
clitag:
|
||||||
|
if: needs.info.outputs.is-release == 'true' && needs.info.outputs.crate == 'cargo-binstall'
|
||||||
|
needs: info
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Push cli release tag
|
||||||
|
uses: mathieudutour/github-tag-action@v6.1
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
custom_tag: ${{ needs.info.outputs.version }}
|
||||||
|
tag_prefix: v
|
||||||
|
- uses: cargo-bins/cargo-binstall@main
|
||||||
|
- name: Create ephemeral keypair
|
||||||
|
id: keypair
|
||||||
|
run: .github/scripts/ephemeral-gen.sh
|
||||||
|
- name: Publish to crates.io
|
||||||
|
env:
|
||||||
|
crate: ${{ needs.info.outputs.crate }}
|
||||||
|
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
||||||
|
run: cargo publish -p "$crate"
|
||||||
|
outputs:
|
||||||
|
signingkey: ${{ steps.keypair.outputs.private }}
|
||||||
|
|
||||||
package:
|
package:
|
||||||
if: needs.info.outputs.is-release == 'true' && needs.info.outputs.crate == 'cargo-binstall'
|
if: needs.info.outputs.is-release == 'true' && needs.info.outputs.crate == 'cargo-binstall'
|
||||||
needs:
|
needs:
|
||||||
- info
|
- info
|
||||||
- tag
|
- clitag
|
||||||
uses: ./.github/workflows/release-build.yml
|
uses: ./.github/workflows/release-build.yml
|
||||||
with:
|
with:
|
||||||
publish: ${{ toJSON(needs.info.outputs) }}
|
publish: ${{ toJSON(needs.info.outputs) }}
|
||||||
|
secrets:
|
||||||
|
signingkey: ${{ needs.clitag.signingkey }}
|
||||||
|
|
|
@ -59,7 +59,7 @@ It may or may not include the untrusted comment; it's ignored by Binstall so we
|
||||||
|
|
||||||
## Just-in-time signing
|
## Just-in-time signing
|
||||||
|
|
||||||
To reduce the risk of a key being stolen, this scheme supports just-in-time signing.
|
To reduce the risk of a key being stolen, this scheme supports just-in-time or "keyless" signing.
|
||||||
The idea is to generate a keypair when releasing, use it for signing the packages, save the key in the Cargo.toml before publishing to a registry, and then discard the private key when it's done.
|
The idea is to generate a keypair when releasing, use it for signing the packages, save the key in the Cargo.toml before publishing to a registry, and then discard the private key when it's done.
|
||||||
That way, there's no key to steal nor to store securely, and every release is signed by a different key.
|
That way, there's no key to steal nor to store securely, and every release is signed by a different key.
|
||||||
And because crates.io is immutable, it's impossible to overwrite the key.
|
And because crates.io is immutable, it's impossible to overwrite the key.
|
||||||
|
@ -73,7 +73,7 @@ There is one caveat to keep in mind: with the scheme as described above, Binstal
|
||||||
The solution here is either:
|
The solution here is either:
|
||||||
|
|
||||||
- Commit the Cargo.toml with the ephemeral public key to the repo when publishing.
|
- Commit the Cargo.toml with the ephemeral public key to the repo when publishing.
|
||||||
- Omit the `[...signing]` section in the source, and write the entire section on publish instead of just filling in the `pubkey`; signatures won't be checked for `--git` installs.
|
- Omit the `[...signing]` section in the source, and write the entire section on publish instead of just filling in the `pubkey`; signatures won't be checked for `--git` installs. Binstall uses this approach.
|
||||||
- Instruct your users to use `--skip-signatures` if they want to install with `--git`.
|
- Instruct your users to use `--skip-signatures` if they want to install with `--git`.
|
||||||
|
|
||||||
## Why not X? (Sigstore, GPG, signify, with SSH keys, ...)
|
## Why not X? (Sigstore, GPG, signify, with SSH keys, ...)
|
||||||
|
@ -84,10 +84,10 @@ We chose minisign as the first supported algorithm as it's lightweight, fairly p
|
||||||
|
|
||||||
## There's a competing project that does package signature verification differently!
|
## There's a competing project that does package signature verification differently!
|
||||||
|
|
||||||
[Tell use about it](https://github.com/cargo-bins/cargo-binstall/issues/1)!
|
[Tell us about it](https://github.com/cargo-bins/cargo-binstall/issues/1)!
|
||||||
We're not looking to fracture the ecosystem here, and will gladly implement support if something exists already.
|
We're not looking to fracture the ecosystem here, and will gladly implement support if something exists already.
|
||||||
|
|
||||||
We'll also work with others in the space to eventually formalise this beyond Binstall, for example around the `cargo-dist.json` metadata format.
|
We'll also work with others in the space to eventually formalise this beyond Binstall, for example around the [`dist-manifest.json`](https://crates.io/crates/cargo-dist-schema) metadata format.
|
||||||
|
|
||||||
## What's the relationship to crate/registry signing?
|
## What's the relationship to crate/registry signing?
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue