Files
DanConwayDev 13d8f24a2d fix(ci): supply a native compiler for crate publication
The v3.0.8 crate publisher failed during Cargo package verification
because its isolated runtime had no cc linker. Include stdenv.cc in
that runtime alongside Rust, pkg-config and OpenSSL metadata.

Share the runtime definition with an empty-environment smoke check
that compiles and runs Rust and OpenSSL-linked C programs. This checks
native linking without relying on the development shell's compiler.
Keep Cargo verification and tag guards intact; signer recovery and
publication retries are outside this change.

Validation: built the crate publisher, crates-toolchain check and
release-scripts check with Nix. No registry publication was attempted.

Assisted-by: GPT-6
2026-10-19 19:21:21 +00:00

92 lines
3.8 KiB
Nix

{ pkgs, rustToolchain, version, ngit }:
let
tools = [ pkgs.git pkgs.coreutils pkgs.python3 ngit ];
context = builtins.readFile ./release-context.sh;
command = name: inputs: text: pkgs.writeShellApplication {
inherit name;
runtimeInputs = tools ++ inputs;
text = context + text;
};
cratesCommand = name: text: pkgs.writeShellApplication {
inherit name text;
runtimeInputs = tools ++ [ rustToolchain pkgs.stdenv.cc pkgs.pkg-config pkgs.openssl ];
runtimeEnv.PKG_CONFIG_PATH = "${pkgs.openssl.dev}/lib/pkgconfig";
};
cratesToolchainCheck = cratesCommand "check-crates-toolchain" ''
printf 'fn main() {}\n' > main.rs
rustc main.rs -o rust-check
./rust-check
printf '#include <openssl/crypto.h>\nint main(void) { return OpenSSL_version_num() == 0; }\n' > main.c
read -r -a openssl_flags <<< "$(pkg-config --cflags --libs openssl)"
cc main.c "''${openssl_flags[@]}" -o native-check
./native-check
'';
provenance = ''
python3 - <<'PYTHON'
import json, os
from pathlib import Path
Path(os.environ["NGIT_CI_OUTPUT_DIR"], "provenance.json").write_text(json.dumps({
"tag": os.environ["NGIT_CI_REF"],
"version": os.environ["version"],
"source_commit": os.environ["release_revision"],
"workflow_commit": os.environ["NGIT_CI_COMMIT_SHA"],
}))
PYTHON
'';
containerCommand = name: workload: import ./ci-container.nix {
inherit pkgs version name;
extraInputs = tools ++ [ pkgs.gnutar ];
workload = context + workload;
};
in {
tools = pkgs.linkFarm "ngit-grasp-publisher-tools"
(map (tool: { name = tool.name; path = tool; }) tools);
commands = {
release-container = containerCommand "ngit-grasp-release-container" ''
[[ $NGIT_CI_TRIGGER == push ]] || { echo 'Use container backfill for manual runs' >&2; exit 1; }
scripts/build-container-layout.sh "$version" "$release_revision" "$NGIT_CI_OUTPUT_DIR/layout"
${provenance}
'';
backfill-container = containerCommand "ngit-grasp-backfill-container" ''
[[ $NGIT_CI_TRIGGER == manual ]] || { echo 'Backfill requires a manual run' >&2; exit 1; }
source_directory=$(mktemp -d "$TMPDIR/backfill-source.XXXXXX")
git archive "$release_revision" | tar -xf - -C "$source_directory"
CONTAINER_CONTEXT="$source_directory" CONTAINER_EXACT_ONLY=true \
scripts/build-container-layout.sh "$version" "$release_revision" "$NGIT_CI_OUTPUT_DIR/layout"
${provenance}
'';
verify-container = containerCommand "ngit-grasp-verify-container" ''
scripts/verify-published-container.sh "$version"
'';
publish-container = command "ngit-grasp-publish-container" [] (builtins.readFile ./publish-container.sh);
publish-release = command "ngit-grasp-publish-release" [] (builtins.readFile ./publish-release.sh);
publish-crates = cratesCommand "ngit-grasp-publish-crates"
(context + builtins.readFile ./publish-crates.sh);
};
checks.release-cli = pkgs.runCommand "ngit-grasp-release-cli-check" {
nativeBuildInputs = [ ngit ];
} ''
ngit release publish --help > release.txt
for option in --nbunksec-file --manifest --channel --tag --commit --released-at --repo-relay-only; do
grep -q -- "$option" release.txt
done
ngit container publish --help > container.txt
for option in --nbunksec-file --manifest --defaults --repo-relay-only; do
grep -q -- "$option" container.txt
done
mkdir -p "$out"
ln -s ${ngit} "$out/ngit"
'';
checks.release-scripts = pkgs.runCommand "ngit-grasp-release-script-tests" {
nativeBuildInputs = [ pkgs.python3 pkgs.bash pkgs.git pkgs.coreutils ];
} ''
python3 ${./release-tests.py} ${./.}
touch "$out"
'';
checks.crates-toolchain = pkgs.runCommand "ngit-grasp-crates-toolchain-check" {} ''
env -i HOME="$TMPDIR" TMPDIR="$TMPDIR" \
${cratesToolchainCheck}/bin/check-crates-toolchain
touch "$out"
'';
}