diff --git a/.github/workflows/main-and-pr.yaml b/.github/workflows/main-and-pr.yaml index c763e65..95e64b6 100644 --- a/.github/workflows/main-and-pr.yaml +++ b/.github/workflows/main-and-pr.yaml @@ -20,5 +20,6 @@ on: jobs: normal: uses: ./.github/workflows/normal.yaml + secrets: inherit with: is_release: false diff --git a/.github/workflows/normal.yaml b/.github/workflows/normal.yaml index 5526ed1..46acbb2 100644 --- a/.github/workflows/normal.yaml +++ b/.github/workflows/normal.yaml @@ -28,102 +28,170 @@ on: type: boolean jobs: - format: - if: ${{ ! inputs.is_release }} + cache: + environment: ci runs-on: ubuntu-latest container: - image: ghcr.io/sdsc-ordes/tripsu:ci-nix-1.0.0 + image: ghcr.io/sdsc-ordes/tripsu:ci-nix-1.1.0 + env: + CACHIX_CACHE_NAME: ${{ secrets.CACHIX_CACHE_NAME }} + CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} steps: + - name: Github Actions Workarounds + run: | + echo "HOME=/root" >> $GITHUB_ENV + cat /container-setup/.ld-library-path >> "$GITHUB_ENV" + - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 1 - - name: Setup Git & Cache Nix + - name: Cache Nix Shell run: | ./tools/ci/setup-git.sh - just nix-develop-ci echo "Built cache." + ./tools/ci/setup-nix-cache.sh + just nix-cache-upload-shell + + format: + environment: ci + if: ${{ ! inputs.is_release }} + runs-on: ubuntu-latest + container: + image: ghcr.io/sdsc-ordes/tripsu:ci-nix-1.1.0 + env: + CACHIX_CACHE_NAME: ${{ secrets.CACHIX_CACHE_NAME }} + CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} + steps: + - name: Github Actions Workarounds + run: | + echo "HOME=/root" >> $GITHUB_ENV + cat /container-setup/.ld-library-path >> "$GITHUB_ENV" + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 1 + - name: Setup + run: | + ./tools/ci/setup-git.sh + ./tools/ci/setup-nix-cache.sh - name: Format run: | just nix-develop-ci just format lint: + environment: ci if: ${{ ! inputs.is_release }} runs-on: ubuntu-latest container: - image: ghcr.io/sdsc-ordes/tripsu:ci-nix-1.0.0 + image: ghcr.io/sdsc-ordes/tripsu:ci-nix-1.1.0 + env: + CACHIX_CACHE_NAME: ${{ secrets.CACHIX_CACHE_NAME }} + CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} steps: + - name: Github Actions Workarounds + run: | + echo "HOME=/root" >> $GITHUB_ENV + cat /container-setup/.ld-library-path >> "$GITHUB_ENV" + - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 1 - - name: Setup Git & Cache Nix + - name: Setup run: | ./tools/ci/setup-git.sh - just nix-develop-ci echo "Built cache." + ./tools/ci/setup-nix-cache.sh - name: Lint run: | just nix-develop-ci just lint build: + environment: ci if: ${{ ! inputs.is_release }} runs-on: ubuntu-latest container: - image: ghcr.io/sdsc-ordes/tripsu:ci-nix-1.0.0 + image: ghcr.io/sdsc-ordes/tripsu:ci-nix-1.1.0 + env: + CACHIX_CACHE_NAME: ${{ secrets.CACHIX_CACHE_NAME }} + CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} steps: + - name: Github Actions Workarounds + run: | + echo "HOME=/root" >> $GITHUB_ENV + cat /container-setup/.ld-library-path >> "$GITHUB_ENV" + - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 1 - - name: Setup Git & Cache Nix + - name: Setup run: | ./tools/ci/setup-git.sh - just nix-develop-ci echo "Built cache." + ./tools/ci/setup-nix-cache.sh - name: Build run: | just nix-develop-ci just build test: + environment: ci runs-on: ubuntu-latest container: - image: ghcr.io/sdsc-ordes/tripsu:ci-nix-1.0.0 + image: ghcr.io/sdsc-ordes/tripsu:ci-nix-1.1.0 + env: + CACHIX_CACHE_NAME: ${{ secrets.CACHIX_CACHE_NAME }} + CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} steps: + - name: Github Actions Workarounds + run: | + echo "HOME=/root" >> $GITHUB_ENV + cat /container-setup/.ld-library-path >> "$GITHUB_ENV" + - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 1 - - name: Setup Git & Cache Nix + - name: Setup run: | ./tools/ci/setup-git.sh - just nix-develop-ci git --version + ./tools/ci/setup-nix-cache.sh - name: Test run: | just nix-develop-ci just test package: + environment: ci runs-on: ubuntu-latest container: - image: ghcr.io/sdsc-ordes/tripsu:ci-nix-1.0.0 + image: ghcr.io/sdsc-ordes/tripsu:ci-nix-1.1.0 + env: + CACHIX_CACHE_NAME: ${{ secrets.CACHIX_CACHE_NAME }} + CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} if: ${{ ! inputs.is_release }} steps: + - name: Github Actions Workarounds + run: | + echo "HOME=/root" >> $GITHUB_ENV + cat /container-setup/.ld-library-path >> "$GITHUB_ENV" + - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 1 - - name: Setup Git + - name: Setup run: | ./tools/ci/setup-git.sh - just nix-develop-ci echo "Built cache." + ./tools/ci/setup-nix-cache.sh - name: Build Package (nix) run: | @@ -134,30 +202,36 @@ jobs: just nix-develop-ci just nix-image deploy: + environment: ci if: ${{ inputs.is_release }} needs: [test] - runs-on: ubuntu-latest container: - image: ghcr.io/sdsc-ordes/tripsu:ci-nix-1.0.0 + image: ghcr.io/sdsc-ordes/tripsu:ci-nix-1.1.0 + env: + CI_IS_RELEASE: true + CACHIX_CACHE_NAME: ${{ secrets.CACHIX_CACHE_NAME }} + CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} permissions: contents: write packages: write - env: - CI_IS_RELEASE: true - steps: + - name: Github Actions Workarounds + run: | + echo "HOME=/root" >> $GITHUB_ENV + cat /container-setup/.ld-library-path >> "$GITHUB_ENV" + - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 1 - - name: Setup Git & Nix Cache + - name: Cache Dev Shell run: | ./tools/ci/setup-git.sh - just nix-develop-ci echo "Built cache." + ./tools/ci/setup-nix-cache.sh - name: Create Version Tag run: | @@ -194,6 +268,9 @@ jobs: contents: write steps: + - name: Define Proper 'HOME' Path + run: echo "HOME=/root" >> $GITHUB_ENV + - name: Checkout uses: actions/checkout@v4 with: diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 382c3fd..62e4639 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -18,5 +18,6 @@ on: jobs: release: uses: ./.github/workflows/normal.yaml + secrets: inherit with: is_release: true diff --git a/.gitignore b/.gitignore index 0354501..0afcef5 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ # Nix result build + +.env diff --git a/justfile b/justfile index c8c7575..0f34535 100644 --- a/justfile +++ b/justfile @@ -15,13 +15,14 @@ nix-develop *args: cd "{{root_dir}}" && \ cmd=("$@") && \ { [ -n "${cmd:-}" ] || cmd=("zsh"); } && \ - nix develop ./tools/nix#default --command "${cmd[@]}" + nix develop ./tools/nix#default --accept-flake-config --command "${cmd[@]}" nix-develop-ci *args: - cd "{{root_dir}}" && \ - cmd=("$@") && \ - { [ -n "${cmd:-}" ] || cmd=("zsh"); } && \ - nix develop ./tools/nix#ci --command "${cmd[@]}" + #!/usr/bin/env bash + set -eu + cd "{{root_dir}}" + cachix watch-exec "$CACHIX_CACHE_NAME" -- \ + nix develop ./tools/nix#ci --accept-flake-config --command "$@" # Enter nix development shell for benchmarking. nix-develop-bench *args: @@ -83,6 +84,27 @@ nix-image *args: cd "{{root_dir}}" && \ "./tools/build-image.sh" "$@" + +# Upload the dev shell to the Nix cache. +nix-cache-upload-shell: + #!/usr/bin/env bash + set -eu + cd "{{root_dir}}" + + profile=./dev-profile + mkdir -p "$profile" + + # Cache development shell. + nix develop --profile "$profile/dev" ./tools/nix#ci --command true + cachix push "$CACHIX_CACHE_NAME" "$profile/dev" + rm -rf "$profile" + + # Cache flake inputs. + nix flake archive ./tools/nix --json \ + | jq -r '.path,(.inputs|to_entries[].value.path)' \ + | cachix push "$CACHIX_CACHE_NAME" + + # Upload all images for CI (local machine) upload-ci-images: cd "{{root_dir}}" && \ diff --git a/tools/ci/images/Containerfile b/tools/ci/images/Containerfile index 27c23cf..173c93b 100644 --- a/tools/ci/images/Containerfile +++ b/tools/ci/images/Containerfile @@ -3,41 +3,31 @@ # or use `nix develop` to start a sandboxed environment to # do other non-docker related stuff. -FROM alpine:latest as base-podman -LABEL org.opencontainers.image.source https://github.com/sdsc-ordes/tripsu -LABEL org.opencontainers.image.description "CI container image for tripsu" -LABEL org.opencontainers.image.license "Apache" - -RUN apk add findutils coreutils git jq curl bash just parallel podman +FROM docker.nix-community.org/nixpkgs/cachix-flakes as base # Nix Image # =============================================== -FROM base-podman as ci-nix -ARG USER_NAME=ci -ARG USER_UID=1000 -ARG USER_GID=1000 -ARG CACHE_TOOLCHAIN=false -ARG USER_HOME="/github/home" +FROM base as ci-nix + +LABEL org.opencontainers.image.source https://github.com/sdsc-ordes/tripsu +LABEL org.opencontainers.image.description "CI container image for tripsu" +LABEL org.opencontainers.image.license "Apache" RUN [ "TARGETPLATFORM" = "linux/amd64" ] || echo "Platform not yet supported." COPY ./tools /container-setup/tools -# Install Nix and pre-cache the env. -RUN bash -c ". /container-setup/tools/general.sh && ci_setup_nix" +# Install Nix. +RUN bash -eu -o pipefail -c \ + ". /container-setup/tools/general.sh && ci_setup_nix" -# Create user (does not work because action/checkout uses `root` in its own container ... 💩) -# Leave this code here for a reference: -# RUN mkdir -p "$USER_HOME" && \ -# adduser "$USER_NAME" -s /bin/zsh -D -u "$USER_UID" -g "$USER_GID" -h "$USER_HOME/$USER_NAME" && \ -# mkdir -p /etc/sudoers.d && \ -# echo "$USER_NAME ALL=(root) NOPASSWD:ALL" > "/etc/sudoers.d/$USER_NAME" && \ -# chmod 0440 "/etc/sudoers.d/$USER_NAME" && \ -# chown -R "$USER_NAME:$USER_NAME" /home /container-setup -# USER "$USER_NAME" - -COPY rust-toolchain.toml /container-setup/ -RUN [ "${CACHE_TOOLCHAIN}" = "false" ] || { cd /container-setup && \ +# Bootstrap the Nix store with some basic utilities. +RUN cd /container-setup && \ git init && git add . && \ - nix --accept-flake-config \ - build --no-link "./tools/nix#devShells.x86_64-linux.ci" && \ - nix store optimise; } + nix profile install --profile /nix/var/nix/profiles/ci \ + --accept-flake-config "./tools/nix#ci.bootstrap" --impure && \ + nix store gc && nix store optimise +ENV PATH="/nix/var/nix/profiles/ci/bin:$PATH" + +RUN bash -eu -o pipefail -c \ + ". /container-setup/tools/general.sh && ci_setup_github_workarounds" && \ + nix store gc && nix store optimise diff --git a/tools/ci/setup-nix-cache.sh b/tools/ci/setup-nix-cache.sh new file mode 100755 index 0000000..3cad841 --- /dev/null +++ b/tools/ci/setup-nix-cache.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +# shellcheck disable=SC1090,SC1091 +# This script is sourced in each step. +set -u +set -e + +ROOT_DIR=$(git rev-parse --show-toplevel) +. "$ROOT_DIR/tools/general.sh" + +ci_setup_cachix "${CACHIX_CACHE_NAME}" "${CACHIX_AUTH_TOKEN}" diff --git a/tools/ci/upload-ci-images.sh b/tools/ci/upload-ci-images.sh index d67d092..071105e 100755 --- a/tools/ci/upload-ci-images.sh +++ b/tools/ci/upload-ci-images.sh @@ -27,7 +27,7 @@ function build_ci_image() { ci_container_mgr push "$image_name" || die "Could not upload image." } -tag="${1:-1.0.0}" +tag="${1:-1.1.0}" repository="${2:-ghcr.io/sdsc-ordes/tripsu}" container_file="$DIR/images/Containerfile" diff --git a/tools/ci/upload-image.sh b/tools/ci/upload-image.sh index 1be4d40..4ba4419 100755 --- a/tools/ci/upload-image.sh +++ b/tools/ci/upload-image.sh @@ -38,11 +38,26 @@ function main() { print_info "Read the image from file '$image_path' and " \ "directly push to registry '$image_name'." + # Write a auth file for skopeo. + local host="${image_name%%/*}" + local auth auth_file + auth=$(echo "$username:$password" | base64) + auth_file=$( + cat <~/.config/nix/nix.conf + +} + +function ci_setup_github_workarounds() { + # Hacks to get the mounted nodejs by github actions work as its dynamically linked + # https://github.com/actions/checkout/issues/334#issuecomment-716068696 + nix build --no-link 'nixpkgs#stdenv.cc.cc.lib' 'nixpkgs#glibc' + local ld_path link + ld_path="$(nix path-info 'nixpkgs#stdenv.cc.cc.lib')/lib" + echo "LD_LIBRARY_PATH=$ld_path" >"/container-setup/.ld-library-path" + link="$(nix path-info 'nixpkgs#glibc' --recursive | grep glibc | grep -v bin)/lib64" || die "Could not get link." + ln -s "$link" /lib64 +} + +function ci_setup_cachix { + local name="$1" + local token="$2" + + print_info "Setup cachix binary cache." + + [ -n "$name" ] || + die "Cachix cache name is empty." + [ -n "$token" ] || + die "Cachix token is empty." + + cachix authtoken --stdin < <(echo "$token") + cachix use --mode user-nixconf "$name" || + die "Could not setup cachix cache '$name'." + + { + echo "extra-trusted-substituters = https://$CACHIX_CACHE_NAME.cachix.org" + echo "narinfo-cache-negative-ttl = 0" + } >>~/.config/nix/nix.conf + + print_info "Cachix binary cache set up." } # Run the container manager which is defined. @@ -89,10 +126,10 @@ function ci_container_mgr() { local mgr="${CONTAINER_MGR:-podman}" if command -v "$mgr" &>/dev/null; then - echo -e "Running '$mgr' as:\n$(printf "'%s' " "podman" "$@")" >&2 + print_info "Running '$mgr' as:\n$(printf "'%s' " "podman" "$@")" >&2 "$mgr" "$@" else - echo -e "Running docker as:\n$(printf "'%s' " "docker" "$@")" + print_info "Running docker as:\n$(printf "'%s' " "docker" "$@")" docker "$@" fi } diff --git a/tools/nix/flake.nix b/tools/nix/flake.nix index 3d44464..d1d70eb 100644 --- a/tools/nix/flake.nix +++ b/tools/nix/flake.nix @@ -3,15 +3,20 @@ nixConfig = { substituters = [ - # Add here some other mirror if needed. - "https://cache.nixos.org/" + "https://cache.nixos.org" ]; extra-substituters = [ + "https://tripsu.cachix.org" # Nix community's cache server "https://nix-community.cachix.org" ]; extra-trusted-public-keys = [ "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + "tripsu.cachix.org-1:pWZmirIwlMxGMVWSDMjQm4R+zLp8gtaT8OfH0Sv/j4E=" + ]; + extra-trusted-substituters = [ + "https://tripsu.cachix.org" + "https://cache.nixos.org" ]; }; @@ -61,24 +66,33 @@ # Set the rust toolchain from the `rust-toolchain.toml`. rustToolchain = pkgs.pkgsBuildHost.rust-bin.fromRustupToolchainFile ../../rust-toolchain.toml; - # Things needed only at compile-time. + # Basic Packages. nativeBuildInputsBasic = with pkgs; [ + procps findutils coreutils + gnugrep bash - zsh curl git + git-lfs jq + just + + # Nix binary cache. + cachix ]; - # Things needed only at compile-time. + # Packges for development. nativeBuildInputsDev = with pkgs; [ + # General build tooling. rustToolchain cargo-watch - just + # Uploading images. skopeo + + # Modifying toml files. dasel ]; @@ -91,14 +105,13 @@ buildInputs = []; # The package of this CLI tool. - # The global version for tripsu. - # This is gonna get tooled later. tripsu = (import ./pkgs/tripsu.nix) { inherit rootDir rustToolchain pkgs lib; }; in with pkgs; rec { devShells = { + # Local development environment. default = mkShell { inherit buildInputs; nativeBuildInputs = nativeBuildInputsBasic ++ nativeBuildInputsDev; @@ -110,6 +123,7 @@ ++ benchInputs; }; + # CI environment. ci = mkShell { inherit buildInputs; nativeBuildInputs = nativeBuildInputsBasic ++ nativeBuildInputsDev; @@ -124,8 +138,20 @@ }; packages = { + # Package of this repo. tripsu = tripsu; + # Packages for CI. + ci = { + # CI bootstrapping packages: + # add some basic utils to the Nix store for CI. + bootstrap = pkgs.buildEnv { + name = "ci-bootstrap"; + paths = nativeBuildInputsBasic; + }; + }; + + # Container Images. images = { ci = (import ./images/ci.nix) { inherit pkgs;