Skip to content

Commit

Permalink
public: only embed a git revision in install.sh on release (#383)
Browse files Browse the repository at this point in the history
To goal of this commit is to get rid of deep cloning the `sdk` repo on CI which
has the advantage that it should be more efficient to evaluate and more
reproducible to build. Note that all other repos already don't deep clone
themselves.

Not deep cloning the repo means that on CI there's no `.git` directory. The only
derivation in `sdk` that used `.git` is `install-sh-release`.

We change its logic as follows:

```
pkgs.runCommandNoCC "install-sh-release" {
  ...
  revision = if src != null && version != "unreleased"
             then "${src.rev} (${version})"
             else "omitted when not a release";
  ...
}
```

On release `version` will be based on the git tag and will be a version number
like `0.5.0`. In that case the revision that gets embedded in `install.sh` is:
`140bc06 (0.5.0)`.

Note that this is the revision corresponding to the `0.5.0` tag and not the
revision of the last commit to `public/install` like it was before!

When not doing a release, like when building locally, on PRs or for `master`,
`version` will be set to `unreleased` and `revision` will be set to a default of
`omitted when not a release`. We do this so that we don't build the
`install-sh-release` derivation for every commit.
  • Loading branch information
basvandijk authored Feb 20, 2020
1 parent 44db26f commit 8b8ea1b
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 89 deletions.
2 changes: 1 addition & 1 deletion default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ rec {

inherit (pkgs) nix-fmt nix-fmt-check;

public = import ./public { inherit pkgs; };
public = import ./public { inherit pkgs src; };
inherit (public) install-sh-release install-sh;

# This is to make sure CI evaluates shell derivations, builds their
Expand Down
2 changes: 1 addition & 1 deletion nix/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
, crossSystem ? null
, config ? {}
, overlays ? []
, releaseVersion ? "latest"
, releaseVersion ? "unreleased"
, RustSec-advisory-db ? null
}:
let
Expand Down
166 changes: 80 additions & 86 deletions public/default.nix
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
{ pkgs ? import ../nix { inherit system; }
, system ? builtins.currentSystem
, src ? null
}:

let
src = pkgs.lib.noNixFiles (pkgs.lib.gitOnlySource ../. "public");
public = pkgs.lib.noNixFiles (pkgs.lib.gitOnlySource ../. "public");
version = pkgs.releaseVersion;
gitDir = pkgs.lib.gitDir ../.;
in

rec {
install-sh =
pkgs.runCommandNoCC "install-sh" {
public = src;
buildInputs = [];
inherit public;
preferLocalBuild = true;
allowSubstitutes = false;
} ''
# git describe --abbrev=7 --tags
mkdir -p $out
Expand All @@ -39,10 +41,11 @@ rec {
shellcheckOpts = "-s sh -S warning";
in
pkgs.runCommandNoCC "install-sh-lint" {
inherit version;
inherit version public;
inherit (pkgs) isMaster;
public = src;
buildInputs = [ install-sh pkgs.shfmt pkgs.shellcheck ];
preferLocalBuild = true;
allowSubstitutes = false;
} ''
set -Eeuo pipefail
# Check if we have an sh compatible script
Expand Down Expand Up @@ -77,85 +80,76 @@ rec {

# The following prepares a manifest for copying install.sh
install-sh-release =
let
# We want to include the last revision of the install script into
# the released version of the script
revision = pkgs.lib.fileContents (
let
commondir = gitDir + "/commondir";
isWorktree = builtins.pathExists commondir;
mainGitDir = gitDir + "/${pkgs.lib.fileContents commondir}";
worktree = pkgs.lib.optionalString isWorktree (
pkgs.lib.dropString (builtins.stringLength (toString mainGitDir))
(toString gitDir)
);
in
pkgs.runCommandNoCC "install_sh_timestamp" {
git_dir = builtins.path {
name = "sdk-git-dir";
path = if isWorktree
then mainGitDir
else gitDir;
};
nativeBuildInputs = [ pkgs.git ];
preferLocalBuild = true;
allowSubstitutes = false;
} ''
cd $git_dir${worktree}
git log -n 1 --pretty=format:%h-%cI -- public/install.sh > $out
''
);
in
pkgs.lib.linuxOnly (
pkgs.runCommandNoCC "install-sh-release" {
inherit version;
inherit (pkgs) isMaster;
inherit revision;
manifest = ./manifest.json;
buildInputs = [ pkgs.jo install-sh-lint install-sh ];
} ''
set -Eeuo pipefail
mkdir -p $out
version_manifest_file=$out/manifest.json
cp $manifest $version_manifest_file
# we stamp the file with the revision
substitute "${install-sh}/install.sh" $out/install.sh \
--subst-var revision
# Creating the manifest
# We name it "_manifest.json" as opposed to "manifest.json" because we
# also export a "manifest.json" (which has nothing to do with the
# release)
hydra_manifest_file=$out/_manifest.json
sha256hashinstall=($(sha256sum "$out/install.sh")) # using this to autosplit on space
sha1hashinstall=($(sha1sum "$out/install.sh")) # using this to autosplit on space
sha256manifest=($(sha256sum "$version_manifest_file")) # using this to autosplit on space
sha1manifest=($(sha1sum "$version_manifest_file")) # using this to autosplit on space
jo -pa \
$(jo package="public" \
version="$version" \
name="installer" \
file="$out/install.sh" \
sha256hash="$sha256hashinstall" \
sha1hash="$sha1hashinstall") \
$(jo package="public" \
version="$version" \
name="manifest.json" \
file="$version_manifest_file" \
sha256hash="$sha256manifest" \
sha1hash="$sha1manifest") >$hydra_manifest_file
# Marking the manifest for publishing
mkdir -p $out/nix-support
echo "upload manifest $hydra_manifest_file" >> \
$out/nix-support/hydra-build-products
''
);
pkgs.lib.linuxOnly (
pkgs.runCommandNoCC "install-sh-release" {
inherit version;
inherit (pkgs) isMaster;

# `revision` will be printed by `install.sh` as follows:
#
# log "Executing DFINITY SDK install script, commit: @revision@"
#
# On release `version` will be based on the git tag and will be a
# version number like `0.5.0`. In that case the revision that gets
# embedded in `install.sh` is: `140bc06 (0.5.0)`.
#
# Note that this is the revision corresponding to the `0.5.0` tag.
#
# When not doing a release, like when building locally, on PRs or for
# `master`, `version` will be set to `unreleased` and `revision` will be set
# to a default of `omitted when not a release`. We do this so that
# we don't build the `install-sh-release` derivation for every commit.
revision =
if src != null && version != "unreleased"
then "${builtins.substring 0 7 src.rev} (${version})"
else "omitted when not a release";

manifest = ./manifest.json;
buildInputs = [ pkgs.jo install-sh-lint install-sh ];
preferLocalBuild = true;
allowSubstitutes = false;
} ''
set -Eeuo pipefail
mkdir -p $out
version_manifest_file=$out/manifest.json
cp $manifest $version_manifest_file
# we stamp the file with the revision
substitute "${install-sh}/install.sh" $out/install.sh \
--subst-var revision
# Creating the manifest
# We name it "_manifest.json" as opposed to "manifest.json" because we
# also export a "manifest.json" (which has nothing to do with the
# release)
hydra_manifest_file=$out/_manifest.json
sha256hashinstall=($(sha256sum "$out/install.sh")) # using this to autosplit on space
sha1hashinstall=($(sha1sum "$out/install.sh")) # using this to autosplit on space
sha256manifest=($(sha256sum "$version_manifest_file")) # using this to autosplit on space
sha1manifest=($(sha1sum "$version_manifest_file")) # using this to autosplit on space
jo -pa \
$(jo package="public" \
version="$version" \
name="installer" \
file="$out/install.sh" \
sha256hash="$sha256hashinstall" \
sha1hash="$sha1hashinstall") \
$(jo package="public" \
version="$version" \
name="manifest.json" \
file="$version_manifest_file" \
sha256hash="$sha256manifest" \
sha1hash="$sha1manifest") >$hydra_manifest_file
# Marking the manifest for publishing
mkdir -p $out/nix-support
echo "upload manifest $hydra_manifest_file" >> \
$out/nix-support/hydra-build-products
''
);
}
2 changes: 1 addition & 1 deletion release.nix
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ let
# versionMatch is `null` if `src.gitTag` is not of the right format like "1.23.456"
# and it's a list of matches like [ "1.23.456" ] when it is.
versionMatches = builtins.match "([0-9]+\.[0-9]+\.[0-9]+)" src.gitTag;
releaseVersion = if versionMatches == null then "latest" else builtins.head versionMatches;
releaseVersion = if versionMatches == null then "unreleased" else builtins.head versionMatches;

pkgs = import ./nix { inherit system config overlays releaseVersion; };

Expand Down

0 comments on commit 8b8ea1b

Please sign in to comment.