Skip to content

Commit 5c9f516

Browse files
authored
cargo-dist (and cargo-release) (#2609)
* wow shiny new cargo-dist CI! * cargo-dist: include installers * tests_expectations is not to be published Makes it play well with cargo-release, where we would get the following: error: tests_expectations is missing the following fields: license || license-file documentation || homepage || repository * add config for cargo-release * too long to fit easy * add some docs * fix docs * fix docs * doc clarification * bump cargo-dist
1 parent 820ca42 commit 5c9f516

File tree

5 files changed

+240
-6
lines changed

5 files changed

+240
-6
lines changed

.github/workflows/release.yml

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# Copyright 2022-2023, axodotdev
2+
# SPDX-License-Identifier: MIT or Apache-2.0
3+
#
4+
# CI that:
5+
#
6+
# * checks for a Git Tag that looks like a release
7+
# * creates a draft Github Release™ and fills in its text
8+
# * builds artifacts with cargo-dist (executable-zips, installers, hashes)
9+
# * uploads those artifacts to the Github Release™
10+
# * undrafts the Github Release™ on success
11+
#
12+
# Note that the Github Release™ will be created before the artifacts,
13+
# so there will be a few minutes where the release has no artifacts
14+
# and then they will slowly trickle in, possibly failing. To make
15+
# this more pleasant we mark the release as a "draft" until all
16+
# artifacts have been successfully uploaded. This allows you to
17+
# choose what to do with partial successes and avoids spamming
18+
# anyone with notifications before the release is actually ready.
19+
name: Release
20+
21+
permissions:
22+
contents: write
23+
24+
# This task will run whenever you push a git tag that looks like a version
25+
# like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc.
26+
# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where
27+
# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION
28+
# must be a Cargo-style SemVer Version (must have at least major.minor.patch).
29+
#
30+
# If PACKAGE_NAME is specified, then the release will be for that
31+
# package (erroring out if it doesn't have the given version or isn't cargo-dist-able).
32+
#
33+
# If PACKAGE_NAME isn't specified, then the release will be for all
34+
# (cargo-dist-able) packages in the workspace with that version (this mode is
35+
# intended for workspaces with only one dist-able package, or with all dist-able
36+
# packages versioned/released in lockstep).
37+
#
38+
# If you push multiple tags at once, separate instances of this workflow will
39+
# spin up, creating an independent Github Release™ for each one. However Github
40+
# will hard limit this to 3 tags per commit, as it will assume more tags is a
41+
# mistake.
42+
#
43+
# If there's a prerelease-style suffix to the version, then the Github Release™
44+
# will be marked as a prerelease.
45+
on:
46+
push:
47+
tags:
48+
- '**[0-9]+.[0-9]+.[0-9]+*'
49+
50+
jobs:
51+
# Run 'cargo dist plan' to determine what tasks we need to do
52+
# and create a draft github release with the computed title/body
53+
plan:
54+
runs-on: ubuntu-latest
55+
outputs:
56+
has-releases: ${{ steps.plan.outputs.has-releases }}
57+
releases: ${{ steps.plan.outputs.releases }}
58+
env:
59+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
60+
steps:
61+
- uses: actions/checkout@v3
62+
with:
63+
submodules: recursive
64+
- name: Install cargo-dist
65+
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.2.0/cargo-dist-installer.sh | sh"
66+
- id: plan
67+
run: |
68+
cargo dist plan --tag=${{ github.ref_name }} --output-format=json > dist-manifest.json
69+
echo "dist plan ran successfully"
70+
cat dist-manifest.json
71+
72+
# Create the Github Release™ based on what cargo-dist thinks it should be
73+
ANNOUNCEMENT_TITLE=$(jq --raw-output ".announcement_title" dist-manifest.json)
74+
IS_PRERELEASE=$(jq --raw-output ".announcement_is_prerelease" dist-manifest.json)
75+
jq --raw-output ".announcement_github_body" dist-manifest.json > new_dist_announcement.md
76+
gh release create ${{ github.ref_name }} --draft --prerelease="$IS_PRERELEASE" --title="$ANNOUNCEMENT_TITLE" --notes-file=new_dist_announcement.md
77+
echo "created announcement!"
78+
79+
# Upload the manifest to the Github Release™
80+
gh release upload ${{ github.ref_name }} dist-manifest.json
81+
echo "uploaded manifest!"
82+
83+
# Disable all the upload-artifacts tasks if we have no actual releases
84+
HAS_RELEASES=$(jq --raw-output ".releases != null" dist-manifest.json)
85+
echo "has-releases=$HAS_RELEASES" >> "$GITHUB_OUTPUT"
86+
echo "releases=$(jq --compact-output ".releases" dist-manifest.json)" >> "$GITHUB_OUTPUT"
87+
88+
# Build and packages all the platform-specific things
89+
upload-local-artifacts:
90+
# Let the initial task tell us to not run (currently very blunt)
91+
needs: plan
92+
if: ${{ needs.plan.outputs.has-releases == 'true' }}
93+
strategy:
94+
fail-fast: false
95+
matrix:
96+
# For these target platforms
97+
include:
98+
- os: "macos-11"
99+
dist-args: "--artifacts=local --target=aarch64-apple-darwin"
100+
install-dist: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.2.0/cargo-dist-installer.sh | sh"
101+
- os: "macos-11"
102+
dist-args: "--artifacts=local --target=x86_64-apple-darwin"
103+
install-dist: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.2.0/cargo-dist-installer.sh | sh"
104+
- os: "windows-2019"
105+
dist-args: "--artifacts=local --target=x86_64-pc-windows-msvc"
106+
install-dist: "irm https://github.com/axodotdev/cargo-dist/releases/download/v0.2.0/cargo-dist-installer.ps1 | iex"
107+
- os: "ubuntu-20.04"
108+
dist-args: "--artifacts=local --target=x86_64-unknown-linux-gnu"
109+
install-dist: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.2.0/cargo-dist-installer.sh | sh"
110+
runs-on: ${{ matrix.os }}
111+
env:
112+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
113+
steps:
114+
- uses: actions/checkout@v3
115+
with:
116+
submodules: recursive
117+
- name: Install cargo-dist
118+
run: ${{ matrix.install-dist }}
119+
- name: Run cargo-dist
120+
# This logic is a bit janky because it's trying to be a polyglot between
121+
# powershell and bash since this will run on windows, macos, and linux!
122+
# The two platforms don't agree on how to talk about env vars but they
123+
# do agree on 'cat' and '$()' so we use that to marshal values between commands.
124+
run: |
125+
# Actually do builds and make zips and whatnot
126+
cargo dist build --tag=${{ github.ref_name }} --output-format=json ${{ matrix.dist-args }} > dist-manifest.json
127+
echo "dist ran successfully"
128+
cat dist-manifest.json
129+
130+
# Parse out what we just built and upload it to the Github Release™
131+
jq --raw-output ".artifacts[]?.path | select( . != null )" dist-manifest.json > uploads.txt
132+
echo "uploading..."
133+
cat uploads.txt
134+
gh release upload ${{ github.ref_name }} $(cat uploads.txt)
135+
echo "uploaded!"
136+
137+
# Build and package all the platform-agnostic(ish) things
138+
upload-global-artifacts:
139+
needs: upload-local-artifacts
140+
runs-on: "ubuntu-20.04"
141+
env:
142+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
143+
steps:
144+
- uses: actions/checkout@v3
145+
with:
146+
submodules: recursive
147+
- name: Install cargo-dist
148+
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.2.0/cargo-dist-installer.sh | sh"
149+
# Get all the local artifacts for the global tasks to use (for e.g. checksums)
150+
- name: Fetch local artifacts
151+
run: |
152+
gh release download ${{ github.ref_name }} --dir target/distrib/
153+
- name: Run cargo-dist
154+
run: |
155+
cargo dist build --tag=${{ github.ref_name }} --output-format=json "--artifacts=global" > dist-manifest.json
156+
echo "dist ran successfully"
157+
cat dist-manifest.json
158+
159+
# Parse out what we just built and upload it to the Github Release™
160+
jq --raw-output ".artifacts[]?.path | select( . != null )" dist-manifest.json > uploads.txt
161+
echo "uploading..."
162+
cat uploads.txt
163+
gh release upload ${{ github.ref_name }} $(cat uploads.txt)
164+
echo "uploaded!"
165+
166+
# Mark the Github Release™ as a non-draft now that everything has succeeded!
167+
publish-release:
168+
# Only run after all the other tasks, but it's ok if upload-artifacts was skipped
169+
needs: [plan, upload-local-artifacts, upload-global-artifacts]
170+
if: ${{ always() && needs.plan.result == 'success' && (needs.upload-local-artifacts.result == 'skipped' || needs.upload-local-artifacts.result == 'success') && (needs.upload-global-artifacts.result == 'skipped' || needs.upload-global-artifacts.result == 'success') }}
171+
runs-on: ubuntu-latest
172+
env:
173+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
174+
steps:
175+
- uses: actions/checkout@v3
176+
with:
177+
submodules: recursive
178+
- name: mark release as non-draft
179+
run: |
180+
gh release edit ${{ github.ref_name }} --draft=false

CONTRIBUTING.md

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -552,10 +552,14 @@ $ npm install doctoc
552552
$ ./node_modules/doctoc/doctoc.js CHANGELOG.md
553553
```
554554

555-
### Bumping the version numbers.
555+
### Bumping the version numbers
556556

557-
Bump version numbers as needed. Run tests just to ensure everything is working
558-
as expected.
557+
Use `cargo release` (from `cargo install cargo-release`) to automate things:
558+
559+
- For a feature release, `cargo release minor --execute` (will bump v0.62.1 to v0.63.0)
560+
- For a patch release, `cargo release patch --execute` (will bump v0.63.0 to v0.63.1)
561+
562+
Run tests just to ensure everything is working as expected.
559563

560564
### Merge to `main`
561565

@@ -567,15 +571,38 @@ important fix) you can skip this.
567571

568572
Once you're in the right commit, do:
569573

574+
```
575+
cargo release [patch|minor] --execute
576+
cargo release --execute
577+
```
578+
This does the equivalent of the following:
579+
570580
```
571581
$ git tag -a v0.62.1 # With the right version of course
572582
$ pushd bindgen && cargo publish && popd
573583
$ pushd bindgen-cli && cargo publish && popd
574584
$ git push --tags upstream # To publish the tag
575585
```
586+
576587
### Create a new release on Github
577588

578-
See [Releasing projects on Github](https://docs.github.com/en/repositories/releasing-projects-on-github)
589+
The release will be automated with the help of `.github/workflows/release.yml`,
590+
and will only be created when all tests succeed.
591+
While the tests are still running,
592+
a draft GitHub release will be created,
593+
to avoid notifying watchers of the repo should a CI step fail.
594+
595+
If everything succeeds,
596+
bindgen cli installers for Linux/MacOS and Windows will be created,
597+
as well as tarballs.
598+
See `[workspace.metadata.dist]` section in Cargo.toml for the configuration.
599+
600+
To update the release configuration,
601+
when a new cargo-dist is available:
579602

603+
```
604+
cargo dist init # from "cargo install cargo-dist"
605+
cargo dist generate-ci # to update .github/workflows/release.yml
606+
```
580607

581608
[prettyplease]: https://github.com/dtolnay/prettyplease

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,29 @@ default-members = [
1313
"bindgen-cli",
1414
"bindgen-tests",
1515
]
16+
17+
# Config for 'cargo dist'
18+
[workspace.metadata.dist]
19+
# The preferred cargo-dist version to use in CI (Cargo.toml SemVer syntax)
20+
cargo-dist-version = "0.2.0"
21+
# CI backends to support (see 'cargo dist generate-ci')
22+
ci = ["github"]
23+
# The installers to generate for each app
24+
installers = ["shell", "powershell"]
25+
# Target platforms to build apps for (Rust target-triple syntax)
26+
targets = [
27+
"x86_64-unknown-linux-gnu",
28+
"x86_64-apple-darwin",
29+
"x86_64-pc-windows-msvc",
30+
"aarch64-apple-darwin",
31+
]
32+
33+
# Config for 'cargo release'
34+
[workspace.metadata.release]
35+
shared-version = true # ensures published packages share the same version
36+
tag-name = "v{{version}}"
37+
38+
# The profile that 'cargo dist' will build with
39+
[profile.dist]
40+
inherits = "release"
41+
lto = "thin"

bindgen-tests/tests/expectations/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
[package]
22
name = "tests_expectations"
33
description = "bindgen results when ran on ../headers/*"
4-
version = "0.1.0"
4+
version = "0.0.0"
55
authors = [
66
"Jyun-Yan You <jyyou.tw@gmail.com>",
77
"Emilio Cobos Álvarez <emilio@crisal.io>",
88
"The Servo project developers",
99
]
1010
edition = "2018"
11+
publish = false
1112

1213
[dependencies]
1314
block = "0.1"

0 commit comments

Comments
 (0)