Skip to content

Commit

Permalink
feat: add docker build
Browse files Browse the repository at this point in the history
  • Loading branch information
loispostula committed Nov 4, 2024
1 parent 33003c1 commit e6b4031
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 80 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cargo-fslabscli"
version = "2.3.2"
version = "2.4.0"
edition = "2021"
authors = ["FSLABS DevOps Gods"]
repository = "https://github.com/ForesightMiningSoftwareCorporation/fslabsci"
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
PHONY: build-artifacts
build-artifacts:
nix flake show --json | jq '.packages."x86_64-linux"|keys[]'| xargs -I {} nix build .#{}
160 changes: 100 additions & 60 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -6,70 +6,110 @@
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
};

outputs = { self, fenix, flake-utils, naersk, nixpkgs, }:
flake-utils.lib.eachDefaultSystem (system:
outputs =
{
self,
fenix,
flake-utils,
naersk,
nixpkgs,
}:
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = (import nixpkgs) { inherit system; };

toolchain = with fenix.packages.${system};
combine [
minimal.rustc
minimal.cargo
targets.x86_64-pc-windows-gnu.latest.rust-std
targets.x86_64-unknown-linux-musl.latest.rust-std
];
makePackage =
rustTarget:
args@{
ccPackage,
nativeBuildInputs ? [ ],
depsBuildBuild ? [ ],
...
}:
let
toolchain =
let
fenixPkgs = fenix.packages.${system};
fenixToolchain =
fenixTarget:
(builtins.getAttr "toolchainOf" fenixTarget) {
channel = "1.80.0";
sha256 = "sha256-6eN/GKzjVSjEhGO9FhWObkRFaE1Jf+uqMSdQnb8lcB4=";
};
in
fenixPkgs.combine [
(fenixToolchain fenixPkgs).rustc
(fenixToolchain fenixPkgs).rustfmt
(fenixToolchain fenixPkgs).cargo
(fenixToolchain fenixPkgs).clippy
(fenixToolchain (fenixPkgs.targets).${rustTarget}).rust-std
];
naersk' = naersk.lib.${system}.override {
cargo = toolchain;
rustc = toolchain;
};
in
naersk'.buildPackage {
src = ./.;
strictDeps = true;
doCheck = false;
release = true;
nativeBuildInputs = nativeBuildInputs ++ [ ccPackage ];
depsBuildBuild = depsBuildBuild ++ [ ccPackage ];
TARGET_CC = "${ccPackage}/bin/${ccPackage.targetPrefix}cc";
CARGO_BUILD_TARGET = rustTarget;
postInstall = ''
cd "$out"/bin
for f in "$(ls)"; do
if ext="$(echo "$f" | grep -oP '\.[a-z]+$')"; then
base="$(echo "$f" | cut -d. -f1)"
mv "$f" "$base-${rustTarget}$ext"
else
mv "$f" "$f-${rustTarget}"
fi
done
'';

naersk' = naersk.lib.${system}.override {
cargo = toolchain;
rustc = toolchain;
};

in rec {
defaultPackage = packages.x86_64-pc-windows-gnu;

packages.x86_64-unknown-linux-musl = naersk'.buildPackage {
src = ./.;
doCheck = true;
nativeBuildInputs = with pkgs; [ pkgsStatic.stdenv.cc ];

# Tells Cargo that we're building for musl.
# (https://doc.rust-lang.org/cargo/reference/config.html#buildtarget)
CARGO_BUILD_TARGET = "x86_64-unknown-linux-musl";
TARGET_CC =
"${pkgs.pkgsStatic.stdenv.cc}/bin/${pkgs.pkgsStatic.stdenv.cc.targetPrefix}cc";
CARGO_BUILD_RUSTFLAGS = [
"-C"
"target-feature=+crt-static"

# -latomic is required to build openssl-sys for armv6l-linux, but
# it doesn't seem to hurt any other builds.
"-C"
"link-args=-static -latomic"

];
};
packages.x86_64-pc-windows-gnu = naersk'.buildPackage {
src = ./.;
strictDeps = true;

depsBuildBuild = with pkgs; [
pkgsCross.mingwW64.stdenv.cc
pkgsCross.mingwW64.windows.pthreads
];

nativeBuildInputs = with pkgs; [ ];

doCheck = false;
}
// args;
targets = {
x86_64-unknown-linux-musl = {
ccPackage = pkgs.pkgsStatic.stdenv.cc;
CARGO_BUILD_RUSTFLAGS = [
"-C"
"target-feature=+crt-static"
"-C"
"link-args=-static -latomic"
];
};
x86_64-pc-windows-gnu = {
ccPackage = pkgs.pkgsCross.mingwW64.stdenv.cc;
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_RUSTFLAGS = "-L native=${pkgs.pkgsCross.mingwW64.windows.pthreads}/lib";

# Tells Cargo that we're building for Windows.
# (https://doc.rust-lang.org/cargo/reference/config.html#buildtarget)
CARGO_BUILD_TARGET = "x86_64-pc-windows-gnu";
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_RUSTFLAGS =
"-L native=${pkgs.pkgsCross.mingwW64.windows.pthreads}/lib";
# Required because ring crate is special. This also seems to have
# fixed some issues with the x86_64-windows cross-compile :shrug:
TARGET_CC =
"${pkgs.pkgsCross.mingwW64.stdenv.cc}/bin/${pkgs.pkgsCross.mingwW64.stdenv.cc.targetPrefix}cc";
depsBuildBuild = with pkgs; [
pkgsCross.mingwW64.windows.pthreads
];
};
};
});
in
rec {
packages = (
nixpkgs.lib.mapAttrs (name: value: (makePackage name value)) targets
// {
release = pkgs.runCommand "release-binaries" { } ''
mkdir -p "$out"/bin
for pkg in ${
builtins.concatStringsSep " " (
map (p: "${p}/bin") (builtins.attrValues (builtins.removeAttrs packages [ "release" ]))
)
}; do
cp -r "$pkg"/* "$out"/bin/
done
(cd "$out"/bin && sha256sum * > sha256.txt)
'';
}
);
}
);
}
7 changes: 0 additions & 7 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
[toolchain]
profile = "default"
channel = "1.80"
targets = [
"x86_64-unknown-linux-gnu",
"x86_64-unknown-linux-musl",
"aarch64-unknown-linux-musl",
"x86_64-pc-windows-gnu"
]

62 changes: 56 additions & 6 deletions src/commands/docker_build_push/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use clap::Parser;
use serde::{Deserialize, Serialize};
use std::fmt::{Display, Formatter};
use std::path::PathBuf;
use std::process::{Command, Stdio};

#[derive(Debug, Parser)]
#[command(about = "Build and Push a docker image")]
Expand All @@ -16,12 +17,12 @@ pub struct Options {
/// Cache export destination (e.g., type=local,dest=path/to/dir)
#[arg(long, env = "DOCKER_CACHE_TO")]
cache_to: Option<String>,
/// Build's context is the set of files located in the specified PATH or URL (default Git context)
#[arg(long, default_value = ".")]
context: String,
/// Path to the Dockerfile. (default {context}/Dockerfile)
/// Build's context is the set of files located in the specified PATH or URL (default to working directory)
#[arg(long)]
file: Option<String>,
context: Option<String>,
/// Path to the Dockerfile. (default {context}/Dockerfile)
#[arg(long, short = 'f', default_value = "Dockerfile")]
file: String,
/// List of metadata for an image
#[arg(long)]
labels: Vec<String>,
Expand Down Expand Up @@ -69,8 +70,57 @@ impl PrettyPrintable for DockerBuildPushResult {

pub async fn docker_build_push(
options: Box<Options>,
_working_directory: PathBuf,
working_directory: PathBuf,
) -> anyhow::Result<DockerBuildPushResult> {
let mut build_command = Command::new("docker");
build_command.arg("build");
build_command.arg("-t").arg(&options.image);

let context = options.context.map(|c| PathBuf::from(c)).unwrap_or_else(|| working_directory);

if let Some(cache_from) = &options.cache_from {
build_command.arg("--cache-from").arg(cache_from);
}
if let Some(cache_to) = &options.cache_to {
build_command.arg("--cache-to").arg(cache_to);
}
options.build_args.iter().for_each(|arg| {
build_command.arg("--build-arg").arg(arg);
});
options.secrets.iter().for_each(|arg| {
build_command.arg("--secret").arg(arg);
});

build_command.arg("--file").arg( context.join(&options.file));

build_command.arg(context);

let output = build_command
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output()?;
if !output.status.success() {
anyhow::bail!("Could not build docker image: {}", String::from_utf8_lossy(&output.stderr));
}
if options.push {
let output = Command::new("docker").arg("push").arg(&options.image).output()?;
if !output.status.success() {
anyhow::bail!("Could not push docker image: {}", String::from_utf8_lossy(&output.stderr));
}
}
for additional_tag in options.additional_tags {
let output = Command::new("docker").arg("tag").arg(&options.image).arg(&additional_tag).output()?;
if !output.status.success() {
anyhow::bail!("Could not tag docker image: {}", String::from_utf8_lossy(&output.stderr));
}
if options.push {
let output = Command::new("docker").arg("push").arg(&additional_tag).output()?;
if !output.status.success() {
anyhow::bail!("Could not push docker image: {}", String::from_utf8_lossy(&output.stderr));
}
}
}

Ok(DockerBuildPushResult {
image_id: "".to_string(),
digest: "".to_string(),
Expand Down
10 changes: 5 additions & 5 deletions src/commands/summaries/run_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,15 @@ pub struct Job<T: JobType<O>, O: RunTypeOutput> {
pub start_time: Option<DateTime<Utc>>,
#[serde(deserialize_with = "deserialize_job_timestamp")]
pub end_time: Option<DateTime<Utc>>,
pub working_directory: String,
// pub working_directory: String,
#[serde(rename = "type")]
pub job_type: T,
pub server_url: String,
// pub server_url: String,
pub repository: String,
pub run_id: String,
pub run_attempt: String,
pub actor: String,
pub event_name: String,
// pub run_attempt: String,
// pub actor: String,
// pub event_name: String,
pub outputs: O,
}

Expand Down

0 comments on commit e6b4031

Please sign in to comment.