Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

replace build script with rust #786

Merged
merged 2 commits into from
Jun 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[alias]
cross-dev = ["run", "--bin", "cross-dev", "--features", "dev", "--"]
build-docker-image = ["cross-dev", "build-docker-image"]
24 changes: 12 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: clippy
args: --locked -- -D warnings
args: --locked --all-targets --all-features -- -D warnings

test:
runs-on: ${{ matrix.os }}
Expand All @@ -74,7 +74,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: test
args: --locked --all-targets --workspace
args: --locked --all-targets --workspace --all-features
timeout-minutes: 5

generate-matrix:
Expand Down Expand Up @@ -206,6 +206,14 @@ jobs:
- name: Set up Docker Buildx
if: runner.os == 'Linux'
uses: docker/setup-buildx-action@v1

- name: Install cross
if: matrix.deploy
run: cargo install --path . --force

- name: Install cross-dev
run: cargo install --path . --force --features=dev --bin cross-dev --debug

- name: Docker Meta
if: runner.os == 'Linux'
id: docker-meta
Expand All @@ -221,7 +229,7 @@ jobs:
id: build-docker-image
if: runner.os == 'Linux'
timeout-minutes: 60
run: ./build-docker-image.sh "${TARGET}"
run: cross-dev build-docker-image "${TARGET}"
env:
TARGET: ${{ matrix.target }}
LABELS: ${{ steps.docker-meta.outputs.labels }}
Expand All @@ -247,14 +255,6 @@ jobs:
RUN: ${{ matrix.run }}
RUNNERS: ${{ matrix.runners }}
shell: bash

- name: Install cross
if: matrix.deploy
run: cargo install --path . --force

- name: Build cross-dev
run: cargo build --features=dev --bin cross-dev

Emilgardis marked this conversation as resolved.
Show resolved Hide resolved
- uses: ./.github/actions/cargo-install-upload-artifacts
if: matrix.deploy
with:
Expand Down Expand Up @@ -287,7 +287,7 @@ jobs:
github.ref == format('refs/heads/{0}', github.event.repository.default_branch) ||
startsWith(github.ref, 'refs/tags/v')
)
run: ./build-docker-image.sh --push "${TARGET}"
run: cross-dev build-docker-image --push "${TARGET}"
env:
TARGET: ${{ matrix.target }}
LABELS: ${{ steps.docker-meta2.outputs.labels }}
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).

### Internal

- #786 - Migrate build script to rust: `cargo build-docker-image $TARGET`
- #730 - make FreeBSD builds more resilient.
- #670 - Use serde for deserialization of Cross.toml
- Change rust edition to 2021 and bump MSRV for the cross binary to 1.58.1
Expand Down
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ edition = "2021"

[features]
default = []
dev = ["serde_yaml"]
dev = ["serde_yaml", "walkdir"]

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

[target.'cfg(not(windows))'.dependencies]
nix = { version = "0.24", default-features = false, features = ["user"] }
Expand Down
106 changes: 0 additions & 106 deletions build-docker-image.sh

This file was deleted.

166 changes: 166 additions & 0 deletions cross-dev/build_docker_image.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
use std::{path::Path, process::Command};

use clap::Args;
use cross::CommandExt;

#[derive(Args, Debug)]
pub struct BuildDockerImage {
#[clap(long, hide = true, env = "GITHUB_REF_TYPE")]
ref_type: Option<String>,
#[clap(long, hide = true, env = "GITHUB_REF_NAME")]
ref_name: Option<String>,
/// Newline separated labels
#[clap(long, env = "LABELS")]
labels: Option<String>,
/// Provide verbose diagnostic output.
#[clap(short, long)]
verbose: bool,
#[clap(long)]
force: bool,
#[clap(short, long)]
push: bool,
#[clap(long, possible_values = ["auto", "plain", "tty"], default_value = "auto")]
progress: String,
/// Container engine (such as docker or podman).
#[clap(long)]
pub engine: Option<String>,

/// Targets to build for
#[clap()]
targets: Vec<String>,
}

pub fn build_docker_image(
BuildDockerImage {
mut targets,
verbose,
force,
push,
progress,
ref_type,
ref_name,
labels,
..
}: BuildDockerImage,
engine: &Path,
) -> cross::Result<()> {
let metadata = cross::cargo_metadata_with_args(
Some(Path::new(env!("CARGO_MANIFEST_DIR"))),
None,
verbose,
)?
.ok_or_else(|| eyre::eyre!("could not find cross workspace and its current version"))?;
let version = metadata
Alexhuszagh marked this conversation as resolved.
Show resolved Hide resolved
.get_package("cross")
.expect("cross expected in workspace")
.version
.clone();
if targets.is_empty() {
targets = walkdir::WalkDir::new(metadata.workspace_root.join("docker"))
.max_depth(1)
.contents_first(true)
.into_iter()
.filter_map(|e| e.ok().filter(|f| f.file_type().is_file()))
.filter_map(|f| {
f.file_name()
.to_string_lossy()
.strip_prefix("Dockerfile.")
.map(ToOwned::to_owned)
})
.collect();
}
for target in targets {
let mut docker_build = Command::new(engine);
docker_build.args(&["buildx", "build"]);
docker_build.current_dir(metadata.workspace_root.join("docker"));

if push {
docker_build.arg("--push");
} else {
docker_build.arg("--load");
}

let dockerfile = format!("Dockerfile.{target}");
let image_name = format!("{}/{target}", cross::CROSS_IMAGE);
let mut tags = vec![];

match (ref_type.as_deref(), ref_name.as_deref()) {
(Some(ref_type), Some(ref_name)) if ref_type == "tag" && ref_name.starts_with('v') => {
let tag_version = ref_name
.strip_prefix('v')
.expect("tag name should start with v");
if version != tag_version {
eyre::bail!("git tag does not match package version.")
}
tags.push(format!("{image_name}:{version}"));
// Check for unstable releases, tag stable releases as `latest`
if version.contains('-') {
// TODO: Don't tag if version is older than currently released version.
tags.push(format!("{image_name}:latest"))
}
}
(Some(ref_type), Some(ref_name)) if ref_type == "branch" => {
tags.push(format!("{image_name}:{ref_name}"));

if ["staging", "trying"]
.iter()
.any(|branch| branch == &ref_name)
{
tags.push(format!("{image_name}:edge"));
}
}
_ => {
if push {
panic!("Refusing to push without tag or branch. {ref_type:?}:{ref_name:?}")
}
tags.push(format!("{image_name}:local"))
}
}

docker_build.arg("--pull");
docker_build.args(&[
"--cache-from",
&format!("type=registry,ref={image_name}:main"),
]);

if push {
docker_build.args(&["--cache-to", "type=inline"]);
}

for tag in &tags {
docker_build.args(&["--tag", tag]);
}

for label in labels
.as_deref()
.unwrap_or("")
.split('\n')
.filter(|s| !s.is_empty())
{
docker_build.args(&["--label", label]);
}

docker_build.args(&["-f", &dockerfile]);

if std::env::var("GITHUB_ACTIONS").is_ok() || progress == "plain" {
docker_build.args(&["--progress", "plain"]);
} else {
docker_build.args(&["--progress", &progress]);
}

docker_build.arg(".");

if force || !push || std::env::var("GITHUB_ACTIONS").is_ok() {
docker_build.run(verbose)?;
} else {
docker_build.print_verbose(true);
}
if std::env::var("GITHUB_ACTIONS").is_ok() {
println!("::set-output name=image::{}", &tags[0])
}
}
if (std::env::var("GITHUB_ACTIONS").is_ok() || !force) && push {
panic!("refusing to push, use --force to override");
}
Ok(())
}