Skip to content

Commit 6f8e1a2

Browse files
authored
CI: Add a release preparation and release workflow (#1559)
* decouple versions again * add prepare-release.yml * add release.yml * cleanup docs and publish.sh * chore: change all variables into lower case * chore: adjust to review * chore: extend instructions for github release * fix: update changes crates correctly * ci: publish workspace on release * chore: fixup release workflow
1 parent 6a3b7f6 commit 6f8e1a2

17 files changed

Lines changed: 203 additions & 245 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"action": "workflow_dispatch",
3+
"inputs": {
4+
"versionBump": "minor"
5+
}
6+
}

.github/scripts/bump-versions.sh

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/usr/bin/env bash
2+
3+
# $fragment: see possible options https://github.com/christian-draeger/increment-semantic-version/tree/1.2.3?tab=readme-ov-file#version-fragment
4+
if [ "$fragment" = "" ]; then
5+
fragment=$1
6+
fi
7+
8+
allowed_crates="protocol oauth core discovery audio metadata playback connect"
9+
10+
if [ "$fragment" = "patch" ]; then
11+
last_tag=$(git describe --tags --abbrev=0)
12+
awk_crates=$(echo "$allowed_crates" | tr ' ' '|')
13+
diff_crates=$(git diff $last_tag... --stat --name-only \
14+
| awk '/\.(rs|proto)$/{print}' \
15+
| awk "/($awk_crates)\//{print}" \
16+
| cut -d '/' -f 1 \
17+
| uniq \
18+
| tr \\n '\ ' \
19+
| xargs )
20+
echo "upgrading the following crates: [$diff_crates]"
21+
else
22+
diff_crates=$allowed_crates
23+
echo "upgrading all crates for consistency"
24+
fi
25+
26+
# append bin so that the version of the binary is also bumped
27+
diff_crates="$diff_crates bin"
28+
29+
# required by script as it's usually a github action
30+
export GITHUB_OUTPUT="version.txt"
31+
# https://github.com/christian-draeger/increment-semantic-version/tree/1.2.3
32+
increment_semver=$(curl https://raw.githubusercontent.com/christian-draeger/increment-semantic-version/refs/tags/1.2.3/entrypoint.sh)
33+
34+
for diff_crate in $diff_crates ; do
35+
if [ "$diff_crate" = "bin" ]; then
36+
toml="./Cargo.toml"
37+
else
38+
toml="./$diff_crate/Cargo.toml"
39+
fi
40+
41+
from="$(cat $toml | awk "/version/{print; exit}" | cut -d\" -f 2)"
42+
43+
# execute script inline, extract result and remove output file
44+
echo "$increment_semver" | bash /dev/stdin $from $fragment
45+
to=$(cat $GITHUB_OUTPUT | cut -d= -f 2)
46+
rm $GITHUB_OUTPUT
47+
48+
echo "upgrading [librespot-$diff_crate] from [$from] to [$to]"
49+
50+
# replace version in associated diff_crate toml
51+
sed -i "0,/$from/{s/$from/$to/}" $toml
52+
53+
if [ "$diff_crate" = "bin" ]; then
54+
continue
55+
fi
56+
57+
# update workspace dependency in root toml
58+
sed -i "/librespot-$diff_crate/{s/$from/$to/}" ./Cargo.toml
59+
60+
# update related dependencies in diff_crate
61+
for allowed_crate in $allowed_crates ; do
62+
cat ./$allowed_crate/Cargo.toml | grep librespot-$diff_crate > /dev/null
63+
if [ $? = 0 ]; then
64+
sed -i "/librespot-$diff_crate/{s/$from/$to/}" ./$allowed_crate/Cargo.toml
65+
fi
66+
done
67+
done
68+
69+
exit 0

.github/workflows/build.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ name: build
1212
- "LICENSE"
1313
- "*.sh"
1414
- "**/Dockerfile*"
15-
- "publish.sh"
1615
- "test.sh"
1716
pull_request:
1817
paths-ignore:
@@ -22,7 +21,6 @@ name: build
2221
- "LICENSE"
2322
- "*.sh"
2423
- "**/Dockerfile*"
25-
- "publish.sh"
2624
- "test.sh"
2725
schedule:
2826
# Run CI every week
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
# test with
3+
# act --job prepare-release --eventpath ./.github/example/prepare-release.event
4+
name: prepare release
5+
on:
6+
workflow_dispatch:
7+
inputs:
8+
versionBump:
9+
description: "Version bump for"
10+
required: true
11+
type: choice
12+
options:
13+
- major
14+
- minor
15+
- patch
16+
17+
jobs:
18+
prepare-release:
19+
name: Prepare release
20+
runs-on: ubuntu-latest
21+
permissions:
22+
contents: write
23+
steps:
24+
- name: Checkout code
25+
uses: actions/checkout@v5
26+
with:
27+
fetch-tags: true
28+
29+
- name: Install Rust toolchain
30+
uses: dtolnay/rust-toolchain@stable
31+
32+
- name: Bump versions
33+
env:
34+
fragment: ${{ github.event.inputs.versionBump }}
35+
run: ./.github/scripts/bump-versions.sh
36+
37+
- name: Update Cargo.lock
38+
run: cargo update --workspace
39+
40+
- name: Get binary version
41+
id: get-version
42+
run: |
43+
VERSION=$(cat ./Cargo.toml | awk "/version/{print; exit}" | cut -d\" -f 2)
44+
echo VERSION=$VERSION >> ${GITHUB_OUTPUT}
45+
46+
- name: Update Changelog
47+
uses: thomaseizinger/[email protected]
48+
with:
49+
tag: v${{ steps.get-version.outputs.VERSION }}
50+
version: ${{ steps.get-version.outputs.VERSION }}
51+
52+
- name: Commit version prepare
53+
uses: stefanzweifel/git-auto-commit-action@v6
54+
if: ${{ !env.ACT }}
55+
with:
56+
commit_message: 'Prepare for v${{ steps.get-version.outputs.VERSION }} release'
57+
file_pattern: '*.md *.toml *.lock'

.github/workflows/release.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: release.yml
2+
on:
3+
release:
4+
types:
5+
- created
6+
workflow_dispatch:
7+
8+
jobs:
9+
publish-crates:
10+
name: Publish librespot
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: read
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v5
17+
18+
- name: Install Rust toolchain
19+
uses: dtolnay/rust-toolchain@stable
20+
21+
- name: Cache Rust dependencies
22+
uses: Swatinem/rust-cache@v2
23+
24+
- name: Install dependencies
25+
run: sudo apt-get update && sudo apt-get install -y libasound2-dev
26+
27+
- name: Verify librespot workspace
28+
run: cargo publish --workspace --dry-run
29+
30+
- name: Publish librespot workspace
31+
if: ${{ !env.ACT }}
32+
env:
33+
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
34+
run: cargo publish --workspace --no-verify

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ will be well worth it.
178178

179179
All these changes are likely to introduce new bugs as well as some regressions.
180180
We appreciate all your testing and contributions to the repository:
181-
https://github.com/librespot-org/librespot
181+
<https://github.com/librespot-org/librespot>
182182

183183
### Changed
184184

Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "librespot"
3-
version.workspace = true
3+
version = "0.7.1"
44
rust-version.workspace = true
55
authors.workspace = true
66
license.workspace = true
@@ -29,7 +29,6 @@ include = [
2929
]
3030

3131
[workspace.package]
32-
version = "0.7.1"
3332
rust-version = "1.85"
3433
authors = ["Librespot Org"]
3534
license = "MIT"

PUBLISHING.md

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,41 @@
22

33
## How To
44

5-
Read through this paragraph in its entirety before running anything.
5+
1. [prepare the release](#prepare-the-release)
6+
2. [create a github-release](#creating-a-github-release)
67

7-
The Bash script in the root of the project, named `publish.sh` can be used to publish a new version of librespot and its corresponding crates. the command should be used as follows from the project root: `./publish 0.1.0` from the project root, substituting the new version number that you wish to publish. *Note the lack of a v prefix on the version number. This is important, do not add one.* The v prefix is added where appropriate by the script.
8+
### Prepare the release
89

9-
Make sure that you are are starting from a clean working directory for both `dev` and `master`, completely up to date with remote and all local changes either committed and pushed or stashed.
10+
For preparing the release a manuel workflow should be available that takes care of the common preparation. But
11+
this can also be done manually if so desired. The workflow does:
12+
- upgrade the version according to the targeted release (`major`, `minor`, `patch`)
13+
- `major` and `minor` require all crates to be updated
14+
- `patch` instead only upgrades the crates that had any changes
15+
- updates the changelog according to Keep-A-Changelog convention
16+
- commits and pushes the changes to remote
1017

11-
Note that the script will update the crates and lockfile, so in case you did not do so before, you really should to make sure none of the dependencies introduce some SemVer breaking change. Then commit so you again have a clean working directory.
18+
### Creating a github-release
1219

13-
Also don't forget to update `CHANGELOG.md` with the version number, release date, and at the bottom the comparison links.
20+
After everything is prepared for the new version. A [new release can be created](https://github.com/librespot-org/librespot/releases/new)
21+
from the ui. The tag will not be available as it isn't set by the prepare workflow, so a new tag needs to be created.
1422

15-
You will want to perform a dry run first: `./publish --dry-run 0.1.0`. Please make note of any errors or warnings. In particular, you may need to explicitly inform Git which remote you want to track for the `master` branch like so: `git --track origin/master` (or whatever you have called the `librespot-org` remote `master` branch).
23+
The tag and name of the release should be named like `v<version>` where `version` is the version of the binary to be
24+
published. As release notes, copy the entries from the changelog for this release.
1625

17-
Depending on your system the script may fail to publish the main `librespot` crate after having published all the `librespot-xyz` sub-crates. If so then make sure the working directory is committed and pushed (watch `Cargo.toml`) and then run `cargo publish` manually after `publish.sh` finished.
26+
The release should be created as draft, which will trigger the workflow that will publish the changed crates and binary.
27+
The workflow will:
28+
- check if all crates needs to be published or only certain crates
29+
- publish the crates in a specific order while excluding crates that didn't have any changes
30+
- publish the binary
1831

19-
To publish the crates your GitHub account needs to be authorized on `crates.io` by `librespot-org`. First time you should run `cargo login` and follow the on-screen instructions.
20-
21-
## What the script does
22-
23-
This is briefly how the script works:
24-
25-
- Change to branch master, pull latest version, merge development branch.
26-
- Change to working directory.
27-
- Change version number in all files.
28-
- Update crates and lockfile.
29-
- Commit and tag changes.
30-
- Publish crates in given order.
31-
- Push version commit and tags to master.
32+
After the workflow was successful the version can be published.
3233

3334
## Notes
3435

35-
Publishing librespot to crates.io is a slightly convoluted affair due to the various dependencies that each package has on other local packages. The order of publising that has been found to work is as follows:
36-
37-
`protocol -> core -> audio -> metadata -> playback -> connect -> librespot`
38-
39-
The `protocol` package needs to be published with `cargo publish --no-verify` due to the build script modifying the source during compile time.
40-
41-
Publishing can be done using the command `cargo publish` in each of the directories of the respective crate.
36+
Publishing librespot to crates.io is a slightly convoluted affair due to the various dependencies that each package has
37+
on other local packages. The order of publishing that has been found to work is as follows:
38+
> `protocol -> core -> audio -> metadata -> playback -> connect -> librespot`
4239
43-
The script is meant to cover the standard publishing process. There are various improvements that could be made, such as adding options such as the user being able to add a changelog, though this is not the main focus, as the script is intended to be run by a CI. Feel free to improve and extend functionality, keeping in mind that it should always be possible for the script to be run in a non-interactive fashion.
40+
The `protocol` package needs to be published with `cargo publish --no-verify` due to the build script modifying the
41+
source during compile time. Publishing can be done using the command `cargo publish` in each of the directories of the
42+
respective crate.

audio/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "librespot-audio"
3-
version.workspace = true
3+
version = "0.7.1"
44
rust-version.workspace = true
55
authors = ["Paul Lietar <[email protected]>"]
66
license.workspace = true

connect/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "librespot-connect"
3-
version.workspace = true
3+
version = "0.7.1"
44
rust-version.workspace = true
55
authors = ["Paul Lietar <[email protected]>"]
66
license.workspace = true

0 commit comments

Comments
 (0)