forked from stepchowfun/toast
-
Notifications
You must be signed in to change notification settings - Fork 0
/
toast.yml
277 lines (240 loc) · 8.87 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
image: ubuntu:20.04
default: build
user: user
command_prefix: |
# Make Bash 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_2022-11-03]. 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-2022-11-03 --frozen --offline fmt --all -- "$@"; }
tasks:
install_packages:
description: Install system packages.
user: root
command: |
# Install the following packages:
#
# - build-essential - Used for linking the binary
# - curl - Used for installing Tagref and Rust
# - lsb-release - Used below to determine the Ubuntu release codename
# - ripgrep - Used for various linting tasks
# - shellcheck - Used for linting shell scripts
apt-get update
apt-get install --yes build-essential curl lsb-release ripgrep shellcheck
# Download Docker's official GPG key.
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# Set up the Docker repository.
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] "\
"https://download.docker.com/linux/ubuntu "\
"$(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list
# Install the Docker CLI.
apt-get update
apt-get install --yes docker-ce-cli
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.
adduser --disabled-password --gecos '' user
install_rust:
description: Install Rust, a systems programming language.
dependencies:
- install_packages
- create_user
command: |
# Install stable Rust [tag:rust_1.65.0].
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- \
-y \
--default-toolchain 1.65.0 \
--profile minimal \
--component clippy
# Add Rust tools to `$PATH`.
. "$HOME/.cargo/env"
# Install nightly Rust [ref:rust_fmt_nightly_2022-11-03].
rustup toolchain install nightly-2022-11-03 --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 toast
cargo-offline clean --release --package toast
# 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
lint:
description: Run the linters.
dependencies:
- build
input_paths:
- .
excluded_input_paths:
- .git
# [tag:excluded_input_paths] Keep this in sync with [ref:gitignore].
- artifacts
- target
command: |
# Lint the code with Clippy.
cargo-offline clippy --all-features --all-targets --workspace
# Check references with Tagref.
tagref
# Lint shell files with ShellCheck.
find . -type f -name '*.sh' | xargs shellcheck
# 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'
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'
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. It's likely that this script is currently running in one of them.
rustup target add x86_64-unknown-linux-gnu
rustup target add x86_64-unknown-linux-musl
# Build the project for both Linux targets with Cargo.
cargo-online build --release --target x86_64-unknown-linux-gnu
cargo-online build --release --target x86_64-unknown-linux-musl
# Move the binaries to a more conveniennt location for exporting.
mkdir artifacts
cp \
target/x86_64-unknown-linux-gnu/release/toast \
artifacts/toast-x86_64-unknown-linux-gnu
cp \
target/x86_64-unknown-linux-musl/release/toast \
artifacts/toast-x86_64-unknown-linux-musl
validate_release:
description: Validate the release.
dependencies:
- release
input_paths:
- integration-tests
cache: false
mount_paths:
- /var/run/docker.sock
user: root
command: |
# Tell the integration tests where the Toast binary lives.
export TOAST="$(pwd)/artifacts/toast-x86_64-unknown-linux-gnu"
# Run the integration tests.
while IFS= read -d '' -r TEST; do
# Log which integration test we're about to run.
echo "Running integration test: $TEST"
# Go into the test directory and run the test.
(cd "$(dirname "$TEST")" > /dev/null && ./run.sh)
done < <(find integration-tests -name run.sh -print0)
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 toast | grep "toast = \"$VERSION\"" > /dev/null; then
echo "Version $VERSION of crate already exists."
exit
fi
# Publish to crates.io.
cargo-online publish --token "$CRATES_IO_TOKEN"