-
Notifications
You must be signed in to change notification settings - Fork 16
235 lines (193 loc) · 7.4 KB
/
Copy pathrelease.yml
File metadata and controls
235 lines (193 loc) · 7.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
name: Release
on:
push:
tags: ['v*']
permissions:
contents: write
env:
CARGO_TERM_COLOR: always
BIN_NAME: budget-tracker
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
jobs:
verify:
name: Verify tag & test
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Install Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
components: clippy, rustfmt
- name: Cache Cargo dependencies
uses: Swatinem/rust-cache@v2
- name: Check tag matches Cargo.toml version
id: version
run: |
tag_version="${GITHUB_REF_NAME#v}"
pkg_version=$(awk -F'"' '/^\[/{s=$0} s=="[package]" && /^version = /{print $2; exit}' Cargo.toml)
bundle_version=$(awk -F'"' '/^\[/{s=$0} s=="[package.metadata.bundle]" && /^version = /{print $2; exit}' Cargo.toml)
echo "tag: $tag_version"
echo "package: $pkg_version"
echo "bundle: $bundle_version"
if [ "$tag_version" != "$pkg_version" ]; then
echo "::error::Tag $GITHUB_REF_NAME does not match [package] version $pkg_version in Cargo.toml."
exit 1
fi
if [ "$tag_version" != "$bundle_version" ]; then
echo "::error::Tag $GITHUB_REF_NAME does not match [package.metadata.bundle] version $bundle_version in Cargo.toml."
exit 1
fi
echo "version=$tag_version" >> "$GITHUB_OUTPUT"
- name: Check formatting
run: cargo fmt --check
- name: Run Clippy
run: cargo clippy -- -D warnings
- name: Run tests
run: cargo test --verbose
- name: Verify the crate packages cleanly for crates.io
run: cargo publish --dry-run --locked
build:
name: Build ${{ matrix.target }}
needs: verify
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
# 22.04 links against an older glibc, which widens the range of
# distributions the gnu binaries will run on. The musl builds are
# fully static (rusqlite is vendored) and run anywhere regardless.
- os: ubuntu-22.04
target: x86_64-unknown-linux-gnu
- os: ubuntu-22.04
target: x86_64-unknown-linux-musl
# arm64 Linux runners are free on public repos, so no cross-compiling.
- os: ubuntu-22.04-arm
target: aarch64-unknown-linux-gnu
- os: ubuntu-22.04-arm
target: aarch64-unknown-linux-musl
# macos-latest runners are Apple Silicon.
- os: macos-latest
target: aarch64-apple-darwin
- os: windows-latest
target: x86_64-pc-windows-msvc
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Install Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
target: ${{ matrix.target }}
- name: Cache Cargo dependencies
uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.target }}
# rusqlite builds SQLite from C source, so musl needs its own compiler.
- name: Install musl toolchain
if: contains(matrix.target, '-musl')
run: sudo apt-get update && sudo apt-get install -y musl-tools
- name: Build release binaries
run: cargo build --release --locked --target ${{ matrix.target }}
- name: Package archive
shell: bash
env:
VERSION: ${{ needs.verify.outputs.version }}
TARGET: ${{ matrix.target }}
run: |
set -euo pipefail
pkg="$BIN_NAME-$VERSION-$TARGET"
out="target/$TARGET/release"
mkdir -p "dist/$pkg"
cp LICENSE README.md "dist/$pkg/"
if [ "$RUNNER_OS" = "Windows" ]; then
cp "$out/$BIN_NAME.exe" "dist/$pkg/"
(cd dist && 7z a -tzip "$pkg.zip" "$pkg" > /dev/null)
else
cp "$out/$BIN_NAME" "dist/$pkg/"
(cd dist && tar czf "$pkg.tar.gz" "$pkg")
fi
rm -rf "dist/$pkg"
ls -l dist
- name: Upload build artifact
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.target }}
path: dist/*
if-no-files-found: error
retention-days: 7
draft_release:
name: Create draft release
needs: [verify, build]
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Download all build artifacts
uses: actions/download-artifact@v8
with:
path: dist
merge-multiple: true
# Package managers pin these hashes in their manifests, so every asset
# needs one and none of them may change after the release is published.
- name: Generate checksums
run: |
set -euo pipefail
(cd dist && sha256sum -- *) > SHA256SUMS
mv SHA256SUMS dist/SHA256SUMS
cat dist/SHA256SUMS
- name: Create or update the draft release
env:
# RELEASE_TOKEN is a personal access token, so the release is
# attributed to the account that owns it rather than to the bot.
# Falls back to the built-in token when the secret is absent.
GH_TOKEN: ${{ secrets.RELEASE_TOKEN || github.token }}
TAG: ${{ github.ref_name }}
VERSION: ${{ needs.verify.outputs.version }}
run: |
if gh release view "$TAG" >/dev/null 2>&1; then
echo "Release $TAG already exists; replacing the assets only."
gh release upload "$TAG" dist/* --clobber
exit 0
fi
gh api "repos/$GITHUB_REPOSITORY/releases/generate-notes" \
-f tag_name="$TAG" \
-q .body > generated_notes.md
{
cat generated_notes.md
echo
cat <<'EOF'
## Install
With Rust installed (skip this if you use the Windows installer below):
```bash
cargo install budget-tracker-tui
```
<details><summary>No Rust? Prebuilt binaries for Linux, macOS, and Windows</summary>
Unpack the archive for your platform and put `budget-tracker` on your PATH.
| Archive | Platform |
| --- | --- |
| `*-x86_64-unknown-linux-gnu.tar.gz` | Linux x86_64 (glibc 2.35+) |
| `*-x86_64-unknown-linux-musl.tar.gz` | Linux x86_64 (static, any distro) |
| `*-aarch64-unknown-linux-gnu.tar.gz` | Linux arm64 (glibc 2.35+) |
| `*-aarch64-unknown-linux-musl.tar.gz` | Linux arm64 (static, any distro) |
| `*-aarch64-apple-darwin.tar.gz` | macOS Apple Silicon |
| `*-x86_64-pc-windows-msvc.zip` | Windows x86_64 |
Verify a download with `sha256sum -c SHA256SUMS --ignore-missing`.
</details>
### TLDR:
<!-- Add the summary, screenshot, and installer before publishing, then delete this line. -->
EOF
} > release_notes.md
gh release create "$TAG" \
--draft \
--verify-tag \
--title "Budget Tracker $VERSION" \
--notes-file release_notes.md \
dist/*
echo "Draft release created: $(gh release view "$TAG" --json url -q .url)"