Skip to content

Commit ca8145b

Browse files
786: replace build script with rust r=Alexhuszagh a=Emilgardis Co-authored-by: Emil Gardström <[email protected]>
2 parents 239e8cb + 952ce20 commit ca8145b

File tree

13 files changed

+400
-318
lines changed

13 files changed

+400
-318
lines changed

.cargo/config.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[alias]
2+
cross-dev = ["run", "--bin", "cross-dev", "--features", "dev", "--"]
3+
build-docker-image = ["cross-dev", "build-docker-image"]

.github/workflows/ci.yml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ jobs:
5454
uses: actions-rs/cargo@v1
5555
with:
5656
command: clippy
57-
args: --locked -- -D warnings
57+
args: --locked --all-targets --all-features -- -D warnings
5858

5959
test:
6060
runs-on: ${{ matrix.os }}
@@ -74,7 +74,7 @@ jobs:
7474
uses: actions-rs/cargo@v1
7575
with:
7676
command: test
77-
args: --locked --all-targets --workspace
77+
args: --locked --all-targets --workspace --all-features
7878
timeout-minutes: 5
7979

8080
generate-matrix:
@@ -206,6 +206,14 @@ jobs:
206206
- name: Set up Docker Buildx
207207
if: runner.os == 'Linux'
208208
uses: docker/setup-buildx-action@v1
209+
210+
- name: Install cross
211+
if: matrix.deploy
212+
run: cargo install --path . --force
213+
214+
- name: Install cross-dev
215+
run: cargo install --path . --force --features=dev --bin cross-dev --debug
216+
209217
- name: Docker Meta
210218
if: runner.os == 'Linux'
211219
id: docker-meta
@@ -221,7 +229,7 @@ jobs:
221229
id: build-docker-image
222230
if: runner.os == 'Linux'
223231
timeout-minutes: 60
224-
run: ./build-docker-image.sh "${TARGET}"
232+
run: cross-dev build-docker-image "${TARGET}"
225233
env:
226234
TARGET: ${{ matrix.target }}
227235
LABELS: ${{ steps.docker-meta.outputs.labels }}
@@ -247,14 +255,6 @@ jobs:
247255
RUN: ${{ matrix.run }}
248256
RUNNERS: ${{ matrix.runners }}
249257
shell: bash
250-
251-
- name: Install cross
252-
if: matrix.deploy
253-
run: cargo install --path . --force
254-
255-
- name: Build cross-dev
256-
run: cargo build --features=dev --bin cross-dev
257-
258258
- uses: ./.github/actions/cargo-install-upload-artifacts
259259
if: matrix.deploy
260260
with:
@@ -287,7 +287,7 @@ jobs:
287287
github.ref == format('refs/heads/{0}', github.event.repository.default_branch) ||
288288
startsWith(github.ref, 'refs/tags/v')
289289
)
290-
run: ./build-docker-image.sh --push "${TARGET}"
290+
run: cross-dev build-docker-image --push "${TARGET}"
291291
env:
292292
TARGET: ${{ matrix.target }}
293293
LABELS: ${{ steps.docker-meta2.outputs.labels }}

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
6363

6464
### Internal
6565

66+
- #786 - Migrate build script to rust: `cargo build-docker-image $TARGET`
6667
- #730 - make FreeBSD builds more resilient.
6768
- #670 - Use serde for deserialization of Cross.toml
6869
- Change rust edition to 2021 and bump MSRV for the cross binary to 1.58.1

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ edition = "2021"
1111

1212
[features]
1313
default = []
14-
dev = ["serde_yaml"]
14+
dev = ["serde_yaml", "walkdir"]
1515

1616
[dependencies]
1717
atty = "0.2"
18-
clap = { version = "3.1.18", features = ["derive"] }
18+
# Pinned until further action to migrate to newer clap, see https://github.com/clap-rs/clap/issues/3822#issuecomment-1154069623
19+
clap = { version = "~3.1", features = ["derive", "env"] }
1920
color-eyre = "0.6"
2021
eyre = "0.6"
2122
home = "0.5"
@@ -28,6 +29,7 @@ serde_json = "1"
2829
serde_yaml = { version = "0.8", optional = true }
2930
serde_ignored = "0.1.2"
3031
shell-words = "1.1.0"
32+
walkdir = { version = "2", optional = true }
3133

3234
[target.'cfg(not(windows))'.dependencies]
3335
nix = { version = "0.24", default-features = false, features = ["user"] }

build-docker-image.sh

Lines changed: 0 additions & 106 deletions
This file was deleted.

cross-dev/build_docker_image.rs

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
use std::{path::Path, process::Command};
2+
3+
use clap::Args;
4+
use cross::CommandExt;
5+
6+
#[derive(Args, Debug)]
7+
pub struct BuildDockerImage {
8+
#[clap(long, hide = true, env = "GITHUB_REF_TYPE")]
9+
ref_type: Option<String>,
10+
#[clap(long, hide = true, env = "GITHUB_REF_NAME")]
11+
ref_name: Option<String>,
12+
/// Newline separated labels
13+
#[clap(long, env = "LABELS")]
14+
labels: Option<String>,
15+
/// Provide verbose diagnostic output.
16+
#[clap(short, long)]
17+
verbose: bool,
18+
#[clap(long)]
19+
force: bool,
20+
#[clap(short, long)]
21+
push: bool,
22+
#[clap(long, possible_values = ["auto", "plain", "tty"], default_value = "auto")]
23+
progress: String,
24+
/// Container engine (such as docker or podman).
25+
#[clap(long)]
26+
pub engine: Option<String>,
27+
28+
/// Targets to build for
29+
#[clap()]
30+
targets: Vec<String>,
31+
}
32+
33+
pub fn build_docker_image(
34+
BuildDockerImage {
35+
mut targets,
36+
verbose,
37+
force,
38+
push,
39+
progress,
40+
ref_type,
41+
ref_name,
42+
labels,
43+
..
44+
}: BuildDockerImage,
45+
engine: &Path,
46+
) -> cross::Result<()> {
47+
let metadata = cross::cargo_metadata_with_args(
48+
Some(Path::new(env!("CARGO_MANIFEST_DIR"))),
49+
None,
50+
verbose,
51+
)?
52+
.ok_or_else(|| eyre::eyre!("could not find cross workspace and its current version"))?;
53+
let version = metadata
54+
.get_package("cross")
55+
.expect("cross expected in workspace")
56+
.version
57+
.clone();
58+
if targets.is_empty() {
59+
targets = walkdir::WalkDir::new(metadata.workspace_root.join("docker"))
60+
.max_depth(1)
61+
.contents_first(true)
62+
.into_iter()
63+
.filter_map(|e| e.ok().filter(|f| f.file_type().is_file()))
64+
.filter_map(|f| {
65+
f.file_name()
66+
.to_string_lossy()
67+
.strip_prefix("Dockerfile.")
68+
.map(ToOwned::to_owned)
69+
})
70+
.collect();
71+
}
72+
for target in targets {
73+
let mut docker_build = Command::new(engine);
74+
docker_build.args(&["buildx", "build"]);
75+
docker_build.current_dir(metadata.workspace_root.join("docker"));
76+
77+
if push {
78+
docker_build.arg("--push");
79+
} else {
80+
docker_build.arg("--load");
81+
}
82+
83+
let dockerfile = format!("Dockerfile.{target}");
84+
let image_name = format!("{}/{target}", cross::CROSS_IMAGE);
85+
let mut tags = vec![];
86+
87+
match (ref_type.as_deref(), ref_name.as_deref()) {
88+
(Some(ref_type), Some(ref_name)) if ref_type == "tag" && ref_name.starts_with('v') => {
89+
let tag_version = ref_name
90+
.strip_prefix('v')
91+
.expect("tag name should start with v");
92+
if version != tag_version {
93+
eyre::bail!("git tag does not match package version.")
94+
}
95+
tags.push(format!("{image_name}:{version}"));
96+
// Check for unstable releases, tag stable releases as `latest`
97+
if version.contains('-') {
98+
// TODO: Don't tag if version is older than currently released version.
99+
tags.push(format!("{image_name}:latest"))
100+
}
101+
}
102+
(Some(ref_type), Some(ref_name)) if ref_type == "branch" => {
103+
tags.push(format!("{image_name}:{ref_name}"));
104+
105+
if ["staging", "trying"]
106+
.iter()
107+
.any(|branch| branch == &ref_name)
108+
{
109+
tags.push(format!("{image_name}:edge"));
110+
}
111+
}
112+
_ => {
113+
if push {
114+
panic!("Refusing to push without tag or branch. {ref_type:?}:{ref_name:?}")
115+
}
116+
tags.push(format!("{image_name}:local"))
117+
}
118+
}
119+
120+
docker_build.arg("--pull");
121+
docker_build.args(&[
122+
"--cache-from",
123+
&format!("type=registry,ref={image_name}:main"),
124+
]);
125+
126+
if push {
127+
docker_build.args(&["--cache-to", "type=inline"]);
128+
}
129+
130+
for tag in &tags {
131+
docker_build.args(&["--tag", tag]);
132+
}
133+
134+
for label in labels
135+
.as_deref()
136+
.unwrap_or("")
137+
.split('\n')
138+
.filter(|s| !s.is_empty())
139+
{
140+
docker_build.args(&["--label", label]);
141+
}
142+
143+
docker_build.args(&["-f", &dockerfile]);
144+
145+
if std::env::var("GITHUB_ACTIONS").is_ok() || progress == "plain" {
146+
docker_build.args(&["--progress", "plain"]);
147+
} else {
148+
docker_build.args(&["--progress", &progress]);
149+
}
150+
151+
docker_build.arg(".");
152+
153+
if force || !push || std::env::var("GITHUB_ACTIONS").is_ok() {
154+
docker_build.run(verbose)?;
155+
} else {
156+
docker_build.print_verbose(true);
157+
}
158+
if std::env::var("GITHUB_ACTIONS").is_ok() {
159+
println!("::set-output name=image::{}", &tags[0])
160+
}
161+
}
162+
if (std::env::var("GITHUB_ACTIONS").is_ok() || !force) && push {
163+
panic!("refusing to push, use --force to override");
164+
}
165+
Ok(())
166+
}

0 commit comments

Comments
 (0)