-
-
Notifications
You must be signed in to change notification settings - Fork 9
/
toast.yml
305 lines (268 loc) · 9.82 KB
/
toast.yml
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
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
image: ubuntu:24.04
default: build
user: user
command_prefix: |
# Make not silently ignore errors.
set -euo pipefail
# Load the Rust startup file, if it exists.
if [ -f "$HOME/.cargo/env" ]; then
. "$HOME/.cargo/env"
fi
# Use this wrapper for `cargo` if network access is needed.
cargo-online () { cargo --locked "$@"; }
# Use this wrapper for `cargo` unless network access is needed.
cargo-offline () { cargo --frozen --offline "$@"; }
# Use this wrapper for formatting code or checking that code is formatted. We use a nightly Rust
# version for the `trailing_comma` formatting option [tag:rust_fmt_nightly_2024-11-28]. The
# nightly version was chosen as the latest available release with all components present
# according to this page:
# https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu.html
cargo-fmt () { cargo +nightly-2024-11-28 --frozen --offline fmt --all -- "$@"; }
# Make Bash log commands.
set -x
tasks:
install_packages:
description: Install system packages.
user: root
command: |
# Install the following packages:
#
# - build-essential - Used to link some crates
# - curl - Used for installing Tagref and Rust
# - gcc-aarch64-linux-gnu - Used for linking the binary for AArch64
# - gcc-x86-64-linux-gnu - Used for linking the binary for x86-64
# - git - Used for testing the pre-commit configuration
# - pre-commit - Used for testing the pre-commit configuration
# - ripgrep - Used for various linting tasks
# - shellcheck - Used for linting shell scripts
apt-get update
apt-get install --yes \
build-essential \
curl \
gcc-aarch64-linux-gnu \
gcc-x86-64-linux-gnu \
git \
pre-commit \
ripgrep \
shellcheck
install_tagref:
description: Install Tagref, a reference checking tool.
dependencies:
- install_packages
user: root
command: |
# Install Tagref using the official installer script.
curl https://raw.githubusercontent.com/stepchowfun/tagref/main/install.sh -LSfs | sh
create_user:
description: Create a user who doesn't have root privileges.
user: root
command: |
# Create a user named `user` with a home directory and with Bash as the login shell.
useradd user --create-home --shell /bin/bash
install_rust:
description: Install Rust, a systems programming language.
dependencies:
- install_packages
- create_user
command: |
# Install stable Rust [tag:rust_1.83.0].
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- \
-y \
--default-toolchain 1.83.0 \
--profile minimal \
--component clippy
# Add Rust tools to `$PATH`.
. "$HOME/.cargo/env"
# Install nightly Rust [ref:rust_fmt_nightly_2024-11-28].
rustup toolchain install nightly-2024-11-28 --profile minimal --component rustfmt
install_tools:
description: Install the tools needed to build and validate the program.
dependencies:
- install_rust
- install_tagref
fetch_crates:
description: Download and build Rust packages used by the program.
dependencies:
- install_tools
input_paths:
- Cargo.lock
- Cargo.toml
command: |
# Create a "hello world" project with the dependencies we want to fetch.
mv Cargo.lock Cargo.lock.og
mv Cargo.toml Cargo.toml.og
cargo-offline init --vcs none
mv Cargo.lock.og Cargo.lock
mv Cargo.toml.og Cargo.toml
# Ask Cargo to build the project in order to fetch the dependencies.
cargo-online build
cargo-online build --release
cargo-online clippy --all-features --all-targets --workspace
# Delete the build artifacts.
cargo-offline clean --package tagref
cargo-offline clean --release --package tagref
# Delete the "hello world" code.
rm -rf src
build:
description: Build the binary in non-release mode.
dependencies:
- fetch_crates
input_paths:
- src
command: |
# Build the project with Cargo.
cargo-offline build
test:
description: Run the test suite.
dependencies:
- build
command: |
# Run the tests with Cargo. The `NO_COLOR` variable is used to disable colored output for
# tests that make assertions regarding the output [tag:colorless_tests].
NO_COLOR=true cargo-offline test
test_precommit:
description: Check that the provided pre-commit configuration works.
dependencies:
- build
input_paths:
- .
excluded_input_paths:
- .git
# [tag:excluded_input_paths_1] Keep this in sync with [file:.gitignore].
- artifacts
- target
command: |
# Set up a Git repository.
git config --global user.email '[email protected]'
git config --global user.name 'Tagref'
git config --global --add safe.directory "$PWD"
git init
git add .
git commit --message 'First commit!'
# Create a pre-commit configuration.
cat << EOF > .pre-commit-config.yaml
repos:
- repo: .
rev: $(git rev-parse HEAD)
hooks:
- id: tagref
EOF
# Run the Tagref hook.
pre-commit run tagref --all-files
lint:
description: Run the linters.
dependencies:
- build
input_paths:
- .
excluded_input_paths:
- .git
# [tag:excluded_input_paths_2] Keep this in sync with [file:.gitignore].
- artifacts
- target
command: |
# Check references with Tagref.
tagref
# Lint shell files with ShellCheck.
find . -type f -name '*.sh' | xargs shellcheck
# Lint the code with Clippy.
cargo-offline clippy --all-features --all-targets --workspace
# Check code formatting with Rustfmt. See [ref:format_macros] for an explanation of the `rg`
# commands.
rg --type rust --files-with-matches '' src | xargs sed -i 's/!(/_(/g'
rg --type rust --files-with-matches '' src | xargs sed -i 's/^\([^ (]*\)_(/\1!(/g'
if ! cargo-fmt --check; then
echo 'ERROR: Please correct the formatting errors above.' 1>&2
exit 1
fi
rg --type rust --files-with-matches '' src | xargs sed -i 's/_(/!(/g'
# Forbid unconsolidated `use` declarations.
if rg --line-number --type rust --multiline '}[[:space]]*;[[:space:]]*\n[[:space:]]*use' src
then
echo 'Please consolidate these `use` declarations.' >&2
exit 1
fi
# Enforce that lines span no more than 100 columns.
if rg --line-number --type rust '.{101}' src; then
echo 'There are lines spanning more than 100 columns.' >&2
exit 1
fi
run:
description: Run the program.
dependencies:
- build
command: |
# Run the program with Cargo.
cargo-offline run -- --help
format:
description: Format the source code.
dependencies:
- fetch_crates
input_paths:
- src
output_paths:
- src
command: |
# Format the code with Rustfmt. We temporarily convert macro invocations into function calls
# so Rustfmt's `trailing_comma` feature applies to macro arguments [tag:format_macros].
rg --type rust --files-with-matches '' src | xargs sed -i 's/!(/_(/g'
rg --type rust --files-with-matches '' src | xargs sed -i 's/^\([^ (]*\)_(/\1!(/g'
cargo-fmt
rg --type rust --files-with-matches '' src | xargs sed -i 's/_(/!(/g'
release:
description: Build and output the release binaries for Linux.
dependencies:
- fetch_crates
input_paths:
- src
output_paths:
- artifacts
command: |
# Add the targets.
rustup target add x86_64-unknown-linux-gnu
rustup target add x86_64-unknown-linux-musl
rustup target add aarch64-unknown-linux-gnu
rustup target add aarch64-unknown-linux-musl
# Set the linkers.
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=x86_64-linux-gnu-gcc
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=x86_64-linux-gnu-gcc
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=aarch64-linux-gnu-gcc
# Build the project with Cargo for each Linux target.
cargo-online build --release --target x86_64-unknown-linux-gnu
cargo-online build --release --target x86_64-unknown-linux-musl
cargo-online build --release --target aarch64-unknown-linux-gnu
cargo-online build --release --target aarch64-unknown-linux-musl
# Move the binaries to a more conveniennt location for exporting.
mkdir artifacts
cp \
target/x86_64-unknown-linux-gnu/release/tagref \
artifacts/tagref-x86_64-unknown-linux-gnu
cp \
target/x86_64-unknown-linux-musl/release/tagref \
artifacts/tagref-x86_64-unknown-linux-musl
cp \
target/aarch64-unknown-linux-gnu/release/tagref \
artifacts/tagref-aarch64-unknown-linux-gnu
cp \
target/aarch64-unknown-linux-musl/release/tagref \
artifacts/tagref-aarch64-unknown-linux-musl
publish:
description: Publish the crate to crates.io.
dependencies:
- fetch_crates
environment:
CRATES_IO_TOKEN: null
input_paths:
- README.md
- src
command: |
# Fetch the program version.
VERSION="$(cargo-offline pkgid | grep --extended-regexp --only-matching '[0-9.]+$')"
# If this version of the package already exists on crates.io, there's nothing more to do.
if cargo-online search tagref | grep "tagref = \"$VERSION\"" > /dev/null; then
echo "Version $VERSION of crate already exists."
exit
fi
# Publish to crates.io.
cargo-online publish --token "$CRATES_IO_TOKEN"