From b245f7a7442acf5cefd4950f71fa044cb27aba88 Mon Sep 17 00:00:00 2001 From: Seth Flynn Date: Mon, 15 Sep 2025 22:58:34 -0400 Subject: [PATCH 1/7] ci: enable use of the experimental installer (cherry picked from commit 2cbbb63628adf5e18150c59f49676d3d074e5eff) --- .../actions/install-nix-action/action.yaml | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/.github/actions/install-nix-action/action.yaml b/.github/actions/install-nix-action/action.yaml index c299b3956..b9861131d 100644 --- a/.github/actions/install-nix-action/action.yaml +++ b/.github/actions/install-nix-action/action.yaml @@ -4,12 +4,18 @@ inputs: dogfood: description: "Whether to use Nix installed from the latest artifact from master branch" required: true # Be explicit about the fact that we are using unreleased artifacts + experimental-installer: + description: "Whether to use the experimental installer to install Nix" + default: false extra_nix_config: description: "Gets appended to `/etc/nix/nix.conf` if passed." install_url: description: "URL of the Nix installer" required: false default: "https://releases.nixos.org/nix/nix-2.30.2/install" + tarball_url: + description: "URL of the Nix tarball to use with the experimental installer" + required: false github_token: description: "Github token" required: true @@ -37,14 +43,57 @@ runs: gh run download "$RUN_ID" --repo "$DOGFOOD_REPO" -n "$INSTALLER_ARTIFACT" -D "$INSTALLER_DOWNLOAD_DIR" echo "installer-path=file://$INSTALLER_DOWNLOAD_DIR" >> "$GITHUB_OUTPUT" + TARBALL_PATH="$(find "$INSTALLER_DOWNLOAD_DIR" -name 'nix*.tar.xz' -print | head -n 1)" + echo "tarball-path=file://$TARBALL_PATH" >> "$GITHUB_OUTPUT" echo "::notice ::Dogfooding Nix installer from master (https://github.com/$DOGFOOD_REPO/actions/runs/$RUN_ID)" env: GH_TOKEN: ${{ inputs.github_token }} DOGFOOD_REPO: "NixOS/nix" + - name: "Download experimental installer" + shell: bash + id: download-experimental-nix-installer + if: ${{ inputs.experimental-installer == 'true' }} + run: | + if [ "$RUNNER_OS" == "Linux" ]; then + INSTALLER_OS="linux" + elif [ "$RUNNER_OS" == "macOS" ]; then + INSTALLER_OS="darwin" + else + echo "::error ::Unsupported RUNNER_OS: $RUNNER_OS" + fi + + if [ "$RUNNER_ARCH" == "X64" ]; then + INSTALLER_ARCH="x86_64" + elif [ "$RUNNER_ARCH" == "ARM64" ]; then + INSTALLER_ARCH="aarch64" + else + echo "::error ::Unsupported RUNNER_ARCH: $RUNNER_ARCH" + fi + + EXPERIMENTAL_INSTALLER_ARTIFACT="nix-installer-$INSTALLER_ARCH-$INSTALLER_OS" + EXPERIMENTAL_INSTALLER_PATH="$GITHUB_WORKSPACE/$EXPERIMENTAL_INSTALLER_ARTIFACT" + # TODO: This uses the latest release. It should probably be pinned, or dogfood the experimental repo's default branch - similar to the above + gh release download -R "$EXPERIMENTAL_INSTALLER_REPO" -D "$EXPERIMENTAL_INSTALLER_PATH" -p "nix-installer.sh" -p "$EXPERIMENTAL_INSTALLER_ARTIFACT" + chmod +x "$EXPERIMENTAL_INSTALLER_PATH/$EXPERIMENTAL_INSTALLER_ARTIFACT" + + echo "installer-path=$EXPERIMENTAL_INSTALLER_PATH" >> "$GITHUB_OUTPUT" + + echo "::notice Using experimental installer from $EXPERIMENTAL_INSTALLER_REPO (https://github.com/$EXPERIMENTAL_INSTALLER_REPO)" + env: + GH_TOKEN: ${{ inputs.github_token }} + EXPERIMENTAL_INSTALLER_REPO: "NixOS/experimental-nix-installer" - uses: cachix/install-nix-action@c134e4c9e34bac6cab09cf239815f9339aaaf84e # v31.5.1 + if: ${{ inputs.experimental-installer != 'true' }} with: # Ternary operator in GHA: https://www.github.com/actions/runner/issues/409#issuecomment-752775072 install_url: ${{ inputs.dogfood == 'true' && format('{0}/install', steps.download-nix-installer.outputs.installer-path) || inputs.install_url }} install_options: ${{ inputs.dogfood == 'true' && format('--tarball-url-prefix {0}', steps.download-nix-installer.outputs.installer-path) || '' }} extra_nix_config: ${{ inputs.extra_nix_config }} + - uses: DeterminateSystems/nix-installer-action@786fff0690178f1234e4e1fe9b536e94f5433196 # v20 + if: ${{ inputs.experimental-installer == 'true' }} + with: + diagnostic-endpoint: "" + local-root: ${{ steps.download-experimental-nix-installer.outputs.installer-path }} + nix-package-url: ${{ inputs.dogfood == 'true' && steps.download-nix-installer.outputs.tarball-path || (inputs.tarball_url || '') }} + extra-conf: ${{ inputs.extra_nix_config }} From 47c43786349fa21e29b2584d377690ae3924d31d Mon Sep 17 00:00:00 2001 From: Seth Flynn Date: Fri, 3 Oct 2025 02:01:03 -0400 Subject: [PATCH 2/7] ci: allow for using the latest build of the experimental installer Until these repos are potentially merged, this is good for dogfooding alongside the experimental installer. It also uses the more official `artifacts.nixos.org` endpoint to install stable releases now More immediately though, we need a patch for the experimental installer to really work in CI at all, and that hasn't landed in a tag yet. So, this lets us use it right from `main`! (cherry picked from commit 92d7381826982f7193145e9fa786eb0f0b1420a2) --- .../actions/install-nix-action/action.yaml | 49 +++++++++++++------ 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/.github/actions/install-nix-action/action.yaml b/.github/actions/install-nix-action/action.yaml index b9861131d..46abea179 100644 --- a/.github/actions/install-nix-action/action.yaml +++ b/.github/actions/install-nix-action/action.yaml @@ -7,6 +7,10 @@ inputs: experimental-installer: description: "Whether to use the experimental installer to install Nix" default: false + experimental-installer-version: + description: "Version of the experimental installer to use. If `latest`, the newest artifact from the default branch is used." + # TODO: This should probably be pinned to a release after https://github.com/NixOS/experimental-nix-installer/pull/49 lands in one + default: "latest" extra_nix_config: description: "Gets appended to `/etc/nix/nix.conf` if passed." install_url: @@ -50,36 +54,51 @@ runs: env: GH_TOKEN: ${{ inputs.github_token }} DOGFOOD_REPO: "NixOS/nix" - - name: "Download experimental installer" + - name: "Gather system info for experimental installer" shell: bash - id: download-experimental-nix-installer if: ${{ inputs.experimental-installer == 'true' }} run: | + echo "::notice Using experimental installer from $EXPERIMENTAL_INSTALLER_REPO (https://github.com/$EXPERIMENTAL_INSTALLER_REPO)" + if [ "$RUNNER_OS" == "Linux" ]; then - INSTALLER_OS="linux" + EXPERIMENTAL_INSTALLER_SYSTEM="linux" + echo "EXPERIMENTAL_INSTALLER_SYSTEM=$EXPERIMENTAL_INSTALLER_SYSTEM" >> "$GITHUB_ENV" elif [ "$RUNNER_OS" == "macOS" ]; then - INSTALLER_OS="darwin" + EXPERIMENTAL_INSTALLER_SYSTEM="darwin" + echo "EXPERIMENTAL_INSTALLER_SYSTEM=$EXPERIMENTAL_INSTALLER_SYSTEM" >> "$GITHUB_ENV" else echo "::error ::Unsupported RUNNER_OS: $RUNNER_OS" + exit 1 fi if [ "$RUNNER_ARCH" == "X64" ]; then - INSTALLER_ARCH="x86_64" + EXPERIMENTAL_INSTALLER_ARCH=x86_64 + echo "EXPERIMENTAL_INSTALLER_ARCH=$EXPERIMENTAL_INSTALLER_ARCH" >> "$GITHUB_ENV" elif [ "$RUNNER_ARCH" == "ARM64" ]; then - INSTALLER_ARCH="aarch64" + EXPERIMENTAL_INSTALLER_ARCH=aarch64 + echo "EXPERIMENTAL_INSTALLER_ARCH=$EXPERIMENTAL_INSTALLER_ARCH" >> "$GITHUB_ENV" else echo "::error ::Unsupported RUNNER_ARCH: $RUNNER_ARCH" + exit 1 fi - EXPERIMENTAL_INSTALLER_ARTIFACT="nix-installer-$INSTALLER_ARCH-$INSTALLER_OS" - EXPERIMENTAL_INSTALLER_PATH="$GITHUB_WORKSPACE/$EXPERIMENTAL_INSTALLER_ARTIFACT" - # TODO: This uses the latest release. It should probably be pinned, or dogfood the experimental repo's default branch - similar to the above - gh release download -R "$EXPERIMENTAL_INSTALLER_REPO" -D "$EXPERIMENTAL_INSTALLER_PATH" -p "nix-installer.sh" -p "$EXPERIMENTAL_INSTALLER_ARTIFACT" - chmod +x "$EXPERIMENTAL_INSTALLER_PATH/$EXPERIMENTAL_INSTALLER_ARTIFACT" + echo "EXPERIMENTAL_INSTALLER_ARTIFACT=nix-installer-$EXPERIMENTAL_INSTALLER_ARCH-$EXPERIMENTAL_INSTALLER_SYSTEM" >> "$GITHUB_ENV" + env: + EXPERIMENTAL_INSTALLER_REPO: "NixOS/experimental-nix-installer" + - name: "Download latest experimental installer" + shell: bash + id: download-latest-experimental-installer + if: ${{ inputs.experimental-installer == 'true' && inputs.experimental-installer-version == 'latest' }} + run: | + RUN_ID=$(gh run list --repo "$EXPERIMENTAL_INSTALLER_REPO" --workflow ci.yml --branch main --status success --json databaseId --jq ".[0].databaseId") - echo "installer-path=$EXPERIMENTAL_INSTALLER_PATH" >> "$GITHUB_OUTPUT" + EXPERIMENTAL_INSTALLER_DOWNLOAD_DIR="$GITHUB_WORKSPACE/$EXPERIMENTAL_INSTALLER_ARTIFACT" + mkdir -p "$EXPERIMENTAL_INSTALLER_DOWNLOAD_DIR" - echo "::notice Using experimental installer from $EXPERIMENTAL_INSTALLER_REPO (https://github.com/$EXPERIMENTAL_INSTALLER_REPO)" + gh run download "$RUN_ID" --repo "$EXPERIMENTAL_INSTALLER_REPO" -n "$EXPERIMENTAL_INSTALLER_ARTIFACT" -D "$EXPERIMENTAL_INSTALLER_DOWNLOAD_DIR" + # Executable permissions are lost in artifacts + find $EXPERIMENTAL_INSTALLER_DOWNLOAD_DIR -type f -exec chmod +x {} + + echo "installer-path=$EXPERIMENTAL_INSTALLER_DOWNLOAD_DIR" >> "$GITHUB_OUTPUT" env: GH_TOKEN: ${{ inputs.github_token }} EXPERIMENTAL_INSTALLER_REPO: "NixOS/experimental-nix-installer" @@ -94,6 +113,8 @@ runs: if: ${{ inputs.experimental-installer == 'true' }} with: diagnostic-endpoint: "" - local-root: ${{ steps.download-experimental-nix-installer.outputs.installer-path }} + # TODO: It'd be nice to use `artifacts.nixos.org` for both of these, maybe through an `/experimental-installer/latest` endpoint? or `/commit/`? + local-root: ${{ inputs.experimental-installer-version == 'latest' && steps.download-latest-experimental-installer.outputs.installer-path || '' }} + source-url: ${{ inputs.experimental-installer-version != 'latest' && 'https://artifacts.nixos.org/experimental-installer/tag/${{ inputs.experimental-installer-version }}/${{ env.EXPERIMENTAL_INSTALLER_ARTIFACT }}' || '' }} nix-package-url: ${{ inputs.dogfood == 'true' && steps.download-nix-installer.outputs.tarball-path || (inputs.tarball_url || '') }} extra-conf: ${{ inputs.extra_nix_config }} From 7644508957ee9bb7402e4f3e64a8b52271ddf789 Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Thu, 23 Oct 2025 02:01:14 +0300 Subject: [PATCH 3/7] ci: Move magic-nix-cache-action into install-nix-action composite This reduces duplication and pins the underlying version of magic-nix-cache, as we already do with other actions. (cherry picked from commit ad5c6a53b91b6d9b0165e0cf09d9397dfd4657d7) --- .github/actions/install-nix-action/action.yaml | 11 +++++++++++ .github/workflows/ci.yml | 6 +----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.github/actions/install-nix-action/action.yaml b/.github/actions/install-nix-action/action.yaml index 46abea179..d694b8eae 100644 --- a/.github/actions/install-nix-action/action.yaml +++ b/.github/actions/install-nix-action/action.yaml @@ -23,6 +23,10 @@ inputs: github_token: description: "Github token" required: true + use_cache: + description: "Whether to setup magic-nix-cache" + default: true + required: false runs: using: "composite" steps: @@ -118,3 +122,10 @@ runs: source-url: ${{ inputs.experimental-installer-version != 'latest' && 'https://artifacts.nixos.org/experimental-installer/tag/${{ inputs.experimental-installer-version }}/${{ env.EXPERIMENTAL_INSTALLER_ARTIFACT }}' || '' }} nix-package-url: ${{ inputs.dogfood == 'true' && steps.download-nix-installer.outputs.tarball-path || (inputs.tarball_url || '') }} extra-conf: ${{ inputs.extra_nix_config }} + - uses: DeterminateSystems/magic-nix-cache-action@565684385bcd71bad329742eefe8d12f2e765b39 # v13 + if: ${{ inputs.use_cache == 'true' }} + with: + diagnostic-endpoint: '' + use-flakehub: false + use-gha-cache: true + source-revision: c2f46a0afa5f95fd4c184a533afd280c68cf63ff # v0.1.6 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dcf0814d8..3177f848a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,6 +27,7 @@ jobs: extra_nix_config: experimental-features = nix-command flakes github_token: ${{ secrets.GITHUB_TOKEN }} + use_cache: false - run: nix flake show --all-systems --json pre-commit-checks: @@ -39,7 +40,6 @@ jobs: dogfood: ${{ github.event_name == 'workflow_dispatch' && inputs.dogfood || github.event_name != 'workflow_dispatch' }} extra_nix_config: experimental-features = nix-command flakes github_token: ${{ secrets.GITHUB_TOKEN }} - - uses: DeterminateSystems/magic-nix-cache-action@main - run: ./ci/gha/tests/pre-commit-checks basic-checks: @@ -90,7 +90,6 @@ jobs: dogfood: ${{ github.event_name == 'workflow_dispatch' && inputs.dogfood || github.event_name != 'workflow_dispatch' }} # The sandbox would otherwise be disabled by default on Darwin extra_nix_config: "sandbox = true" - - uses: DeterminateSystems/magic-nix-cache-action@main # Since ubuntu 22.30, unprivileged usernamespaces are no longer allowed to map to the root user: # https://ubuntu.com/blog/ubuntu-23-10-restricted-unprivileged-user-namespaces - run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 @@ -201,7 +200,6 @@ jobs: - uses: cachix/install-nix-action@v31 with: install_url: https://releases.nixos.org/nix/nix-2.20.3/install - - uses: DeterminateSystems/magic-nix-cache-action@main - run: echo NIX_VERSION="$(nix --experimental-features 'nix-command flakes' eval .\#nix.version | tr -d \")" >> $GITHUB_ENV - run: nix --experimental-features 'nix-command flakes' build .#dockerImage -L - run: docker load -i ./result/image.tar.gz @@ -280,7 +278,6 @@ jobs: extra_nix_config: experimental-features = nix-command flakes github_token: ${{ secrets.GITHUB_TOKEN }} - - uses: DeterminateSystems/magic-nix-cache-action@main - run: nix build -L --out-link ./new-nix && PATH=$(pwd)/new-nix/bin:$PATH MAX_FLAKES=25 flake-regressions/eval-all.sh profile_build: @@ -301,7 +298,6 @@ jobs: extra_nix_config: | experimental-features = flakes nix-command ca-derivations impure-derivations max-jobs = 1 - - uses: DeterminateSystems/magic-nix-cache-action@main - run: | nix build -L --file ./ci/gha/profile-build buildTimeReport --out-link build-time-report.md cat build-time-report.md >> $GITHUB_STEP_SUMMARY From 9e842a3bfc185a72db1cc81f53fbc976e8b57032 Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Fri, 24 Oct 2025 01:34:06 +0300 Subject: [PATCH 4/7] ci: Bump magic-nix-cache with post-build-hook fix No tagged release with the fix for [^]. [^]: https://github.com/DeterminateSystems/magic-nix-cache/commit/578f01e1473129cc289d579ba6dee9cdac40aeab (cherry picked from commit 4c4eb5d07fc59513fb44ca348b42a33015a65e50) --- .github/actions/install-nix-action/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/install-nix-action/action.yaml b/.github/actions/install-nix-action/action.yaml index d694b8eae..df7339e75 100644 --- a/.github/actions/install-nix-action/action.yaml +++ b/.github/actions/install-nix-action/action.yaml @@ -128,4 +128,4 @@ runs: diagnostic-endpoint: '' use-flakehub: false use-gha-cache: true - source-revision: c2f46a0afa5f95fd4c184a533afd280c68cf63ff # v0.1.6 + source-revision: 92d9581367be2233c2d5714a2640e1339f4087d8 # main From be2053886d87e56fe7653b4aa06ba801ddcbfcd0 Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Sun, 28 Dec 2025 02:21:52 +0300 Subject: [PATCH 5/7] ci: Move docker_push_image into a separate workflow Best reviewed with -w --color-moved. This just moves the code into a separate workflow. This will allow us to reuse it in the release job for github releng of releases. (cherry picked from commit 745983dfc057c6b645cad93190be9fab0058208e) --- .github/workflows/ci.yml | 74 +++------------------------ .github/workflows/docker-push.yml | 84 +++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 67 deletions(-) create mode 100644 .github/workflows/docker-push.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3177f848a..71ac2beac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -164,77 +164,17 @@ jobs: - run: exec bash -c "nix-channel --add https://releases.nixos.org/nixos/unstable/nixos-23.05pre466020.60c1d71f2ba nixpkgs" - run: exec bash -c "nix-channel --update && nix-env -iA nixpkgs.hello && hello" - # Steps to test CI automation in your own fork. - # 1. Sign-up for https://hub.docker.com/ - # 2. Store your dockerhub username as DOCKERHUB_USERNAME in "Repository secrets" of your fork repository settings (https://github.com/$githubuser/nix/settings/secrets/actions) - # 3. Create an access token in https://hub.docker.com/settings/security and store it as DOCKERHUB_TOKEN in "Repository secrets" of your fork - check_secrets: - permissions: - contents: none - name: Check presence of secrets - runs-on: ubuntu-24.04 - outputs: - docker: ${{ steps.secret.outputs.docker }} - steps: - - name: Check for DockerHub secrets - id: secret - env: - _DOCKER_SECRETS: ${{ secrets.DOCKERHUB_USERNAME }}${{ secrets.DOCKERHUB_TOKEN }} - run: | - echo "docker=${{ env._DOCKER_SECRETS != '' }}" >> $GITHUB_OUTPUT - docker_push_image: - needs: [tests, vm_tests, check_secrets] + name: Push docker image to DockerHub and GHCR + needs: [tests, vm_tests] + if: github.event_name == 'push' && github.ref_name == 'master' + uses: ./.github/workflows/docker-push.yml permissions: contents: read packages: write - if: >- - needs.check_secrets.outputs.docker == 'true' && - github.event_name == 'push' && - github.ref_name == 'master' - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@v5 - with: - fetch-depth: 0 - - uses: cachix/install-nix-action@v31 - with: - install_url: https://releases.nixos.org/nix/nix-2.20.3/install - - run: echo NIX_VERSION="$(nix --experimental-features 'nix-command flakes' eval .\#nix.version | tr -d \")" >> $GITHUB_ENV - - run: nix --experimental-features 'nix-command flakes' build .#dockerImage -L - - run: docker load -i ./result/image.tar.gz - - run: docker tag nix:$NIX_VERSION ${{ secrets.DOCKERHUB_USERNAME }}/nix:$NIX_VERSION - - run: docker tag nix:$NIX_VERSION ${{ secrets.DOCKERHUB_USERNAME }}/nix:master - # We'll deploy the newly built image to both Docker Hub and Github Container Registry. - # - # Push to Docker Hub first - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/nix:$NIX_VERSION - - run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/nix:master - # Push to GitHub Container Registry as well - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Push image - run: | - IMAGE_ID=ghcr.io/${{ github.repository_owner }}/nix - # Change all uppercase to lowercase - IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') - - docker tag nix:$NIX_VERSION $IMAGE_ID:$NIX_VERSION - docker tag nix:$NIX_VERSION $IMAGE_ID:latest - docker push $IMAGE_ID:$NIX_VERSION - docker push $IMAGE_ID:latest - # deprecated 2024-02-24 - docker tag nix:$NIX_VERSION $IMAGE_ID:master - docker push $IMAGE_ID:master + secrets: + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} vm_tests: needs: basic-checks diff --git a/.github/workflows/docker-push.yml b/.github/workflows/docker-push.yml new file mode 100644 index 000000000..152a8fa10 --- /dev/null +++ b/.github/workflows/docker-push.yml @@ -0,0 +1,84 @@ +name: "Push Docker Image" + +on: + workflow_call: + secrets: + DOCKERHUB_USERNAME: + required: true + DOCKERHUB_TOKEN: + required: true + +permissions: {} + +jobs: + # Steps to test CI automation in your own fork. + # 1. Sign-up for https://hub.docker.com/ + # 2. Store your dockerhub username as DOCKERHUB_USERNAME in "Repository secrets" of your fork repository settings (https://github.com/$githubuser/nix/settings/secrets/actions) + # 3. Create an access token in https://hub.docker.com/settings/security and store it as DOCKERHUB_TOKEN in "Repository secrets" of your fork + check_secrets: + permissions: + contents: none + name: Check presence of secrets + runs-on: ubuntu-24.04 + outputs: + docker: ${{ steps.secret.outputs.docker }} + steps: + - name: Check for DockerHub secrets + id: secret + env: + _DOCKER_SECRETS: ${{ secrets.DOCKERHUB_USERNAME }}${{ secrets.DOCKERHUB_TOKEN }} + run: | + echo "docker=${{ env._DOCKER_SECRETS != '' }}" >> $GITHUB_OUTPUT + + push: + name: Push docker image to DockerHub and GHCR + needs: [check_secrets] + permissions: + contents: read + packages: write + if: needs.check_secrets.outputs.docker == 'true' + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + - uses: ./.github/actions/install-nix-action + with: + dogfood: false + extra_nix_config: | + experimental-features = flakes nix-command + - run: echo NIX_VERSION="$(nix eval .\#nix.version | tr -d \")" >> $GITHUB_ENV + - run: nix build .#dockerImage -L + - run: docker load -i ./result/image.tar.gz + - run: docker tag nix:$NIX_VERSION ${{ secrets.DOCKERHUB_USERNAME }}/nix:$NIX_VERSION + - run: docker tag nix:$NIX_VERSION ${{ secrets.DOCKERHUB_USERNAME }}/nix:master + # We'll deploy the newly built image to both Docker Hub and Github Container Registry. + # + # Push to Docker Hub first + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/nix:$NIX_VERSION + - run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/nix:master + # Push to GitHub Container Registry as well + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Push image + run: | + IMAGE_ID=ghcr.io/${{ github.repository_owner }}/nix + # Change all uppercase to lowercase + IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') + + docker tag nix:$NIX_VERSION $IMAGE_ID:$NIX_VERSION + docker tag nix:$NIX_VERSION $IMAGE_ID:latest + docker push $IMAGE_ID:$NIX_VERSION + docker push $IMAGE_ID:latest + # deprecated 2024-02-24 + docker tag nix:$NIX_VERSION $IMAGE_ID:master + docker push $IMAGE_ID:master From 4624f61dfba4609f780d5a580a4e3ce266e0b595 Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Sun, 28 Dec 2025 02:36:54 +0300 Subject: [PATCH 6/7] ci: Pin actions in docker-push reusable workflow (cherry picked from commit fb05f6de0d508225d0724c3e87052b5606a623d2) --- .github/workflows/docker-push.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-push.yml b/.github/workflows/docker-push.yml index 152a8fa10..450b06ea9 100644 --- a/.github/workflows/docker-push.yml +++ b/.github/workflows/docker-push.yml @@ -39,7 +39,7 @@ jobs: if: needs.check_secrets.outputs.docker == 'true' runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: fetch-depth: 0 - uses: ./.github/actions/install-nix-action @@ -56,7 +56,7 @@ jobs: # # Push to Docker Hub first - name: Login to Docker Hub - uses: docker/login-action@v3 + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} @@ -64,7 +64,7 @@ jobs: - run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/nix:master # Push to GitHub Container Registry as well - name: Login to GitHub Container Registry - uses: docker/login-action@v3 + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 with: registry: ghcr.io username: ${{ github.actor }} From d6342a8656df5ef94a2d56446a49b3b3e6b8ec7d Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Sun, 28 Dec 2025 03:24:19 +0300 Subject: [PATCH 7/7] ci: Make docker-push workflow more configurable This should allow reusing this workflow (with more tweaks) in the releng workflow. (cherry picked from commit c867ed6726ffd0cf739b14d08917b86fd3492ff2) --- .github/workflows/ci.yml | 3 +++ .github/workflows/docker-push.yml | 44 +++++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 71ac2beac..cc55c01a0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -169,6 +169,9 @@ jobs: needs: [tests, vm_tests] if: github.event_name == 'push' && github.ref_name == 'master' uses: ./.github/workflows/docker-push.yml + with: + ref: ${{ github.sha }} + is_master: true permissions: contents: read packages: write diff --git a/.github/workflows/docker-push.yml b/.github/workflows/docker-push.yml index 450b06ea9..d83b391e5 100644 --- a/.github/workflows/docker-push.yml +++ b/.github/workflows/docker-push.yml @@ -2,6 +2,15 @@ name: "Push Docker Image" on: workflow_call: + inputs: + ref: + description: "Git ref to build the docker image from" + required: true + type: string + is_master: + description: "Whether run from master branch" + required: true + type: boolean secrets: DOCKERHUB_USERNAME: required: true @@ -42,6 +51,7 @@ jobs: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: fetch-depth: 0 + ref: ${{ inputs.ref }} - uses: ./.github/actions/install-nix-action with: dogfood: false @@ -50,8 +60,6 @@ jobs: - run: echo NIX_VERSION="$(nix eval .\#nix.version | tr -d \")" >> $GITHUB_ENV - run: nix build .#dockerImage -L - run: docker load -i ./result/image.tar.gz - - run: docker tag nix:$NIX_VERSION ${{ secrets.DOCKERHUB_USERNAME }}/nix:$NIX_VERSION - - run: docker tag nix:$NIX_VERSION ${{ secrets.DOCKERHUB_USERNAME }}/nix:master # We'll deploy the newly built image to both Docker Hub and Github Container Registry. # # Push to Docker Hub first @@ -60,8 +68,17 @@ jobs: with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/nix:$NIX_VERSION - - run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/nix:master + - name: Push to Docker Hub + env: + IS_MASTER: ${{ inputs.is_master }} + DOCKERHUB_REPO: ${{ secrets.DOCKERHUB_USERNAME }}/nix + run: | + docker tag nix:$NIX_VERSION $DOCKERHUB_REPO:$NIX_VERSION + docker push $DOCKERHUB_REPO:$NIX_VERSION + if [ "$IS_MASTER" = "true" ]; then + docker tag nix:$NIX_VERSION $DOCKERHUB_REPO:master + docker push $DOCKERHUB_REPO:master + fi # Push to GitHub Container Registry as well - name: Login to GitHub Container Registry uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 @@ -69,16 +86,21 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Push image + - name: Push to GHCR + env: + IS_MASTER: ${{ inputs.is_master }} run: | IMAGE_ID=ghcr.io/${{ github.repository_owner }}/nix - # Change all uppercase to lowercase IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') docker tag nix:$NIX_VERSION $IMAGE_ID:$NIX_VERSION - docker tag nix:$NIX_VERSION $IMAGE_ID:latest docker push $IMAGE_ID:$NIX_VERSION - docker push $IMAGE_ID:latest - # deprecated 2024-02-24 - docker tag nix:$NIX_VERSION $IMAGE_ID:master - docker push $IMAGE_ID:master + if [ "$IS_MASTER" = "true" ]; then + # FIXME: Do not tag master as latest. Upload to GHCR as part of + # releng instead. Possibly adapt this reusable workflow for the (yet + # nonexistent) release workflow. + docker tag nix:$NIX_VERSION $IMAGE_ID:latest + docker tag nix:$NIX_VERSION $IMAGE_ID:master + docker push $IMAGE_ID:latest + docker push $IMAGE_ID:master + fi