From c5eebac6675f0dfc6733705c7136f8b9044dd565 Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Mon, 29 Dec 2025 02:26:49 +0300 Subject: [PATCH 1/6] maintainers/upload-release.pl: Make more configurable This allows for testing with a local minio deployment like: ./upload-release.pl --skip-docker --skip-git --s3-endpoint http://localhost:9000 --s3-host localhost:9000 1821360 (cherry picked from commit d19b8d5f992f68ede23f928a296f7872971041e7) --- maintainers/upload-release.pl | 222 ++++++++++++++++++++-------------- 1 file changed, 134 insertions(+), 88 deletions(-) diff --git a/maintainers/upload-release.pl b/maintainers/upload-release.pl index 31a9c71d543..19666590ed6 100755 --- a/maintainers/upload-release.pl +++ b/maintainers/upload-release.pl @@ -1,7 +1,8 @@ #! /usr/bin/env nix-shell -#! nix-shell -i perl -p perl perlPackages.LWPUserAgent perlPackages.LWPProtocolHttps perlPackages.FileSlurp perlPackages.NetAmazonS3 gnupg1 +#! nix-shell -i perl -p awscli perl perlPackages.LWPUserAgent perlPackages.LWPProtocolHttps perlPackages.FileSlurp perlPackages.NetAmazonS3 perlPackages.GetoptLongDescriptive gnupg1 use strict; +use Getopt::Long::Descriptive; use Data::Dumper; use File::Basename; use File::Path; @@ -13,7 +14,30 @@ delete $ENV{'shell'}; # shut up a LWP::UserAgent.pm warning -my $evalId = $ARGV[0] or die "Usage: $0 EVAL-ID\n"; +my ($opt, $usage) = describe_options( + '%c %o ', + [ 'skip-docker', 'Skip Docker image upload' ], + [ 'skip-git', 'Skip Git tagging' ], + [ 'skip-s3', 'Skip S3 upload' ], + [ 'docker-owner=s', 'Docker image owner', { default => 'nixos/nix' } ], + [ 'project-root=s', 'Pristine git repository path' ], + [ 's3-endpoint=s', 'Custom S3 endpoint' ], + [ 's3-host=s', 'S3 host', { default => 's3-eu-west-1.amazonaws.com' } ], + [], + [ 'help|h', 'Show this help message', { shortcircuit => 1 } ], + [], + [ 'Environment variables:' ], + [ 'AWS_ACCESS_KEY_ID' ], + [ 'AWS_SECRET_ACCESS_KEY' ], + [ 'AWS_SESSION_TOKEN For OIDC' ], + [ 'IS_LATEST Set to "1" to mark as latest release' ], +); + +print($usage->text), exit if $opt->help; + +my $evalId = $ARGV[0] or do { print STDERR $usage->text; exit 1 }; + +die "--project-root is required unless --skip-git is specified\n" unless $opt->skip_git || $opt->project_root; my $releasesBucketName = "nix-releases"; my $channelsBucketName = "nix-channels"; @@ -62,25 +86,38 @@ sub fetch { my $binaryCache = "https://cache.nixos.org/?local-nar-cache=$narCache"; # S3 setup. -my $aws_access_key_id = $ENV{'AWS_ACCESS_KEY_ID'} or die "No AWS_ACCESS_KEY_ID given."; -my $aws_secret_access_key = $ENV{'AWS_SECRET_ACCESS_KEY'} or die "No AWS_SECRET_ACCESS_KEY given."; - -my $s3 = Net::Amazon::S3->new( - { aws_access_key_id => $aws_access_key_id, - aws_secret_access_key => $aws_secret_access_key, - retry => 1, - host => "s3-eu-west-1.amazonaws.com", - }); - -my $releasesBucket = $s3->bucket($releasesBucketName) or die; - -my $s3_us = Net::Amazon::S3->new( - { aws_access_key_id => $aws_access_key_id, - aws_secret_access_key => $aws_secret_access_key, - retry => 1, - }); - -my $channelsBucket = $s3_us->bucket($channelsBucketName) or die; +my $aws_access_key_id = $ENV{'AWS_ACCESS_KEY_ID'}; +my $aws_secret_access_key = $ENV{'AWS_SECRET_ACCESS_KEY'}; +my $aws_session_token = $ENV{'AWS_SESSION_TOKEN'}; + +my ($s3, $releasesBucket, $s3_channels, $channelsBucket); + +unless ($opt->skip_s3) { + $aws_access_key_id or die "No AWS_ACCESS_KEY_ID given."; + $aws_secret_access_key or die "No AWS_SECRET_ACCESS_KEY given."; + + $s3 = Net::Amazon::S3->new( + { aws_access_key_id => $aws_access_key_id, + aws_secret_access_key => $aws_secret_access_key, + $aws_session_token ? (aws_session_token => $aws_session_token) : (), + retry => 1, + host => $opt->s3_host, + secure => ($opt->s3_endpoint && $opt->s3_endpoint =~ /^http:/) ? 0 : 1, + }); + + $releasesBucket = $s3->bucket($releasesBucketName) or die; + + $s3_channels = Net::Amazon::S3->new( + { aws_access_key_id => $aws_access_key_id, + aws_secret_access_key => $aws_secret_access_key, + $aws_session_token ? (aws_session_token => $aws_session_token) : (), + retry => 1, + host => $opt->s3_host, + secure => ($opt->s3_endpoint && $opt->s3_endpoint =~ /^http:/) ? 0 : 1, + }); + + $channelsBucket = $s3_channels->bucket($channelsBucketName) or die; +} sub getStorePath { my ($jobName, $output) = @_; @@ -115,11 +152,12 @@ sub copyManual { File::Path::remove_tree("$tmpDir/manual.tmp", {safe => 1}); } - system("aws s3 sync '$tmpDir/manual' s3://$releasesBucketName/$releaseDir/manual") == 0 + my $awsEndpoint = $opt->s3_endpoint ? "--endpoint-url " . $opt->s3_endpoint : ""; + system("aws $awsEndpoint s3 sync '$tmpDir/manual' s3://$releasesBucketName/$releaseDir/manual") == 0 or die "syncing manual to S3\n"; } -copyManual; +copyManual unless $opt->skip_s3; sub downloadFile { my ($jobName, $productNr, $dstName) = @_; @@ -158,30 +196,12 @@ sub downloadFile { return $sha256_expected; } -downloadFile("binaryTarball.i686-linux", "1"); -downloadFile("binaryTarball.x86_64-linux", "1"); -downloadFile("binaryTarball.aarch64-linux", "1"); -downloadFile("binaryTarball.x86_64-darwin", "1"); -downloadFile("binaryTarball.aarch64-darwin", "1"); -eval { - downloadFile("binaryTarballCross.x86_64-linux.armv6l-unknown-linux-gnueabihf", "1"); -}; -warn "$@" if $@; -eval { - downloadFile("binaryTarballCross.x86_64-linux.armv7l-unknown-linux-gnueabihf", "1"); -}; -warn "$@" if $@; -eval { - downloadFile("binaryTarballCross.x86_64-linux.riscv64-unknown-linux-gnu", "1"); -}; -warn "$@" if $@; -downloadFile("installerScript", "1"); - -# Upload docker images to dockerhub. +# Upload docker images. my $dockerManifest = ""; my $dockerManifestLatest = ""; my $haveDocker = 0; +unless ($opt->skip_docker) { for my $platforms (["x86_64-linux", "amd64"], ["aarch64-linux", "arm64"]) { my $system = $platforms->[0]; my $dockerPlatform = $platforms->[1]; @@ -195,8 +215,8 @@ sub downloadFile { print STDERR "loading docker image for $dockerPlatform...\n"; system("docker load -i $tmpDir/$fn") == 0 or die; - my $tag = "nixos/nix:$version-$dockerPlatform"; - my $latestTag = "nixos/nix:latest-$dockerPlatform"; + my $tag = $opt->docker_owner . ":$version-$dockerPlatform"; + my $latestTag = $opt->docker_owner . ":latest-$dockerPlatform"; print STDERR "tagging $version docker image for $dockerPlatform...\n"; system("docker tag nix:$version $tag") == 0 or die; @@ -219,68 +239,94 @@ sub downloadFile { } if ($haveDocker) { + my $dockerOwner = $opt->docker_owner; print STDERR "creating multi-platform docker manifest...\n"; - system("docker manifest rm nixos/nix:$version"); - system("docker manifest create nixos/nix:$version $dockerManifest") == 0 or die; + system("docker manifest rm $dockerOwner:$version"); + system("docker manifest create $dockerOwner:$version $dockerManifest") == 0 or die; if ($isLatest) { print STDERR "creating latest multi-platform docker manifest...\n"; - system("docker manifest rm nixos/nix:latest"); - system("docker manifest create nixos/nix:latest $dockerManifestLatest") == 0 or die; + system("docker manifest rm $dockerOwner:latest"); + system("docker manifest create $dockerOwner:latest $dockerManifestLatest") == 0 or die; } print STDERR "pushing multi-platform docker manifest...\n"; - system("docker manifest push nixos/nix:$version") == 0 or die; + system("docker manifest push $dockerOwner:$version") == 0 or die; if ($isLatest) { print STDERR "pushing latest multi-platform docker manifest...\n"; - system("docker manifest push nixos/nix:latest") == 0 or die; + system("docker manifest push $dockerOwner:latest") == 0 or die; } } +} -# Upload nix-fallback-paths.nix. -write_file("$tmpDir/fallback-paths.nix", - "{\n" . - " x86_64-linux = \"" . getStorePath("build.nix-everything.x86_64-linux") . "\";\n" . - " i686-linux = \"" . getStorePath("build.nix-everything.i686-linux") . "\";\n" . - " aarch64-linux = \"" . getStorePath("build.nix-everything.aarch64-linux") . "\";\n" . - " riscv64-linux = \"" . getStorePath("buildCross.nix-everything.riscv64-unknown-linux-gnu.x86_64-linux") . "\";\n" . - " x86_64-darwin = \"" . getStorePath("build.nix-everything.x86_64-darwin") . "\";\n" . - " aarch64-darwin = \"" . getStorePath("build.nix-everything.aarch64-darwin") . "\";\n" . - "}\n"); # Upload release files to S3. -for my $fn (glob "$tmpDir/*") { - my $name = basename($fn); - next if $name eq "manual"; - my $dstKey = "$releaseDir/" . $name; - unless (defined $releasesBucket->head_key($dstKey)) { - print STDERR "uploading $fn to s3://$releasesBucketName/$dstKey...\n"; - - my $configuration = (); - $configuration->{content_type} = "application/octet-stream"; - - if ($fn =~ /.sha256|install|\.nix$/) { - $configuration->{content_type} = "text/plain"; +unless ($opt->skip_s3) { + downloadFile("binaryTarball.i686-linux", "1"); + downloadFile("binaryTarball.x86_64-linux", "1"); + downloadFile("binaryTarball.aarch64-linux", "1"); + downloadFile("binaryTarball.x86_64-darwin", "1"); + downloadFile("binaryTarball.aarch64-darwin", "1"); + eval { + downloadFile("binaryTarballCross.x86_64-linux.armv6l-unknown-linux-gnueabihf", "1"); + }; + warn "$@" if $@; + eval { + downloadFile("binaryTarballCross.x86_64-linux.armv7l-unknown-linux-gnueabihf", "1"); + }; + warn "$@" if $@; + eval { + downloadFile("binaryTarballCross.x86_64-linux.riscv64-unknown-linux-gnu", "1"); + }; + warn "$@" if $@; + downloadFile("installerScript", "1"); + + # Upload nix-fallback-paths.nix. + write_file("$tmpDir/fallback-paths.nix", + "{\n" . + " x86_64-linux = \"" . getStorePath("build.nix-everything.x86_64-linux") . "\";\n" . + " i686-linux = \"" . getStorePath("build.nix-everything.i686-linux") . "\";\n" . + " aarch64-linux = \"" . getStorePath("build.nix-everything.aarch64-linux") . "\";\n" . + " riscv64-linux = \"" . getStorePath("buildCross.nix-everything.riscv64-unknown-linux-gnu.x86_64-linux") . "\";\n" . + " x86_64-darwin = \"" . getStorePath("build.nix-everything.x86_64-darwin") . "\";\n" . + " aarch64-darwin = \"" . getStorePath("build.nix-everything.aarch64-darwin") . "\";\n" . + "}\n"); + + for my $fn (glob "$tmpDir/*") { + my $name = basename($fn); + next if $name eq "manual"; + my $dstKey = "$releaseDir/" . $name; + unless (defined $releasesBucket->head_key($dstKey)) { + print STDERR "uploading $fn to s3://$releasesBucketName/$dstKey...\n"; + + my $configuration = (); + $configuration->{content_type} = "application/octet-stream"; + + if ($fn =~ /.sha256|install|\.nix$/) { + $configuration->{content_type} = "text/plain"; + } + + $releasesBucket->add_key_filename($dstKey, $fn, $configuration) + or die $releasesBucket->err . ": " . $releasesBucket->errstr; } - - $releasesBucket->add_key_filename($dstKey, $fn, $configuration) - or die $releasesBucket->err . ": " . $releasesBucket->errstr; } -} -# Update the "latest" symlink. -$channelsBucket->add_key( - "nix-latest/install", "", - { "x-amz-website-redirect-location" => "https://releases.nixos.org/$releaseDir/install" }) - or die $channelsBucket->err . ": " . $channelsBucket->errstr - if $isLatest; + # Update the "latest" symlink. + $channelsBucket->add_key( + "nix-latest/install", "", + { "x-amz-website-redirect-location" => "https://releases.nixos.org/$releaseDir/install" }) + or die $channelsBucket->err . ": " . $channelsBucket->errstr + if $isLatest; +} # Tag the release in Git. -chdir("/home/eelco/Dev/nix-pristine") or die; -system("git remote update origin") == 0 or die; -system("git tag --force --sign $version $nixRev -m 'Tagging release $version'") == 0 or die; -system("git push --tags") == 0 or die; -system("git push --force-with-lease origin $nixRev:refs/heads/latest-release") == 0 or die if $isLatest; +unless ($opt->skip_git) { + chdir($opt->project_root) or die "Cannot chdir to " . $opt->project_root . ": $!"; + system("git remote update origin") == 0 or die; + system("git tag --force --sign $version $nixRev -m 'Tagging release $version'") == 0 or die; + system("git push --tags") == 0 or die; + system("git push --force-with-lease origin $nixRev:refs/heads/latest-release") == 0 or die if $isLatest; +} File::Path::remove_tree($narCache, {safe => 1}); File::Path::remove_tree($tmpDir, {safe => 1}); From 4b161a8684f8dbd7fdbf34bb8cf4275b6b9fa3dc Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Mon, 29 Dec 2025 03:34:16 +0300 Subject: [PATCH 2/6] maintainers: Document git tag signing Previously it was only Eeclo doing releases that were signed with B541D55301270E0BCF15CA5D8170B4726D7198DE. Other linux distributions have the expectation (rightfully so) that our tags are signed. Let's document this. We could do cross-signing to make tracing the chain of trust easier for all Nix team members [1]. [1]: https://nixos.org/community/teams/nix/ (cherry picked from commit 6cb8b58a47789a208b28e8590358cb95da90bbb3) --- ...8A6F530EA202E5F651611314FAEA63448E1DF9.asc | 110 ++++++++++++++++++ ...41D55301270E0BCF15CA5D8170B4726D7198DE.asc | 51 ++++++++ maintainers/keys/README.md | 13 +++ maintainers/release-process.md | 2 +- 4 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 maintainers/keys/158A6F530EA202E5F651611314FAEA63448E1DF9.asc create mode 100644 maintainers/keys/B541D55301270E0BCF15CA5D8170B4726D7198DE.asc create mode 100644 maintainers/keys/README.md diff --git a/maintainers/keys/158A6F530EA202E5F651611314FAEA63448E1DF9.asc b/maintainers/keys/158A6F530EA202E5F651611314FAEA63448E1DF9.asc new file mode 100644 index 00000000000..ea00c2c3d54 --- /dev/null +++ b/maintainers/keys/158A6F530EA202E5F651611314FAEA63448E1DF9.asc @@ -0,0 +1,110 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +7w== +=mXYP +-----END PGP PUBLIC KEY BLOCK----- diff --git a/maintainers/keys/B541D55301270E0BCF15CA5D8170B4726D7198DE.asc b/maintainers/keys/B541D55301270E0BCF15CA5D8170B4726D7198DE.asc new file mode 100644 index 00000000000..dee0aef4cc6 --- /dev/null +++ b/maintainers/keys/B541D55301270E0BCF15CA5D8170B4726D7198DE.asc @@ -0,0 +1,51 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=u5cX +-----END PGP PUBLIC KEY BLOCK----- diff --git a/maintainers/keys/README.md b/maintainers/keys/README.md new file mode 100644 index 00000000000..ef473eada79 --- /dev/null +++ b/maintainers/keys/README.md @@ -0,0 +1,13 @@ +# Maintainer GPG Keys + +Release tags are signed by members of the [Nix maintainer team](https://nixos.org/community/teams/nix/) as part of the [release process](../release-process.md). This directory contains the public GPG keys used for signing. + +## Keys + +- **Eelco Dolstra** + GPG Fingerprint: `B541 D553 0127 0E0B CF15 CA5D 8170 B472 6D71 98DE` + +- **Sergei Zimmerman** + GPG Fingerprint: [`158A 6F53 0EA2 02E5 F651 6113 14FA EA63 448E 1DF9`](https://keys.openpgp.org/vks/v1/by-fingerprint/158A6F530EA202E5F651611314FAEA63448E1DF9) + + diff --git a/maintainers/release-process.md b/maintainers/release-process.md index 790618b7f4c..b79902e7377 100644 --- a/maintainers/release-process.md +++ b/maintainers/release-process.md @@ -5,7 +5,7 @@ The release process is intended to create the following for each release: -* A Git tag +* A signed Git tag (public keys in `maintainers/keys/`) * Binary tarballs in https://releases.nixos.org/?prefix=nix/ From 485d9c522fceeedc896888a7aa1763bc589901cc Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Mon, 29 Dec 2025 03:31:37 +0300 Subject: [PATCH 3/6] ci: Add upload-release.yml This workflow is supposed to automate release uploads by using OIDC for AWS setup. DockerHub still uses long-lived credentials, but that's not fixable. In a follow-up we could set up release uploads to GHCR too. (cherry picked from commit 4599daa10e29a0588ee410e1c72d0fd6b33adb81) --- .github/workflows/upload-release.yml | 52 ++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 .github/workflows/upload-release.yml diff --git a/.github/workflows/upload-release.yml b/.github/workflows/upload-release.yml new file mode 100644 index 00000000000..7beb3e8c9dc --- /dev/null +++ b/.github/workflows/upload-release.yml @@ -0,0 +1,52 @@ +name: Upload Release +on: + workflow_dispatch: + inputs: + eval_id: + description: "Hydra evaluation ID" + required: true + type: number + is_latest: + description: "Mark as latest release" + required: false + type: boolean + default: false +permissions: + contents: read + id-token: write +jobs: + release: + runs-on: ubuntu-24.04 + environment: releases + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: ./.github/actions/install-nix-action + with: + dogfood: false # Use stable version + use_cache: false # Don't want any cache injection shenanigans + extra_nix_config: | + experimental-features = nix-command flakes + - name: Set NIX_PATH from flake input + run: | + NIXPKGS_PATH=$(nix build --inputs-from .# nixpkgs#path --print-out-paths --no-link) + # Shebangs with perl have issues. Pin nixpkgs this way. nix shell should maybe + # get the same uberhack that nix-shell has to support it. + echo "NIX_PATH=nixpkgs=$NIXPKGS_PATH" >> "$GITHUB_ENV" + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1 + with: + role-to-assume: "arn:aws:iam::080433136561:role/nix-release" + role-session-name: nix-release-oidc-${{ github.run_id }} + aws-region: eu-west-1 + - name: Login to Docker Hub + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Upload release + run: | + ./maintainers/upload-release.pl \ + ${{ inputs.eval_id }} \ + --skip-git + env: + IS_LATEST: ${{ inputs.is_latest && '1' || '' }} From 44cfdd0b0183d2b20a5776d3967eef42360b0260 Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Mon, 29 Dec 2025 23:01:54 +0300 Subject: [PATCH 4/6] upload-release: Also push to GHCR as part of the release process (cherry picked from commit a1569458cccef17153f8f69dba7ef64c2f347b7c) --- .github/workflows/docker-push.yml | 5 ----- .github/workflows/upload-release.yml | 17 +++++++++++++++++ maintainers/release-process.md | 2 +- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/.github/workflows/docker-push.yml b/.github/workflows/docker-push.yml index d83b391e546..c4ccd1fe0d0 100644 --- a/.github/workflows/docker-push.yml +++ b/.github/workflows/docker-push.yml @@ -96,11 +96,6 @@ jobs: docker tag nix:$NIX_VERSION $IMAGE_ID:$NIX_VERSION docker push $IMAGE_ID:$NIX_VERSION 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 diff --git a/.github/workflows/upload-release.yml b/.github/workflows/upload-release.yml index 7beb3e8c9dc..82ce0c40b74 100644 --- a/.github/workflows/upload-release.yml +++ b/.github/workflows/upload-release.yml @@ -14,6 +14,7 @@ on: permissions: contents: read id-token: write + packages: write jobs: release: runs-on: ubuntu-24.04 @@ -43,6 +44,12 @@ jobs: with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Login to GitHub Container Registry + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Upload release run: | ./maintainers/upload-release.pl \ @@ -50,3 +57,13 @@ jobs: --skip-git env: IS_LATEST: ${{ inputs.is_latest && '1' || '' }} + - name: Push to GHCR + run: | + DOCKER_OWNER="ghcr.io/$(echo '${{ github.repository_owner }}' | tr '[A-Z]' '[a-z]')/nix" + ./maintainers/upload-release.pl \ + ${{ inputs.eval_id }} \ + --skip-git \ + --skip-s3 \ + --docker-owner "$DOCKER_OWNER" + env: + IS_LATEST: ${{ inputs.is_latest && '1' || '' }} diff --git a/maintainers/release-process.md b/maintainers/release-process.md index b79902e7377..3bc2379780e 100644 --- a/maintainers/release-process.md +++ b/maintainers/release-process.md @@ -9,7 +9,7 @@ release: * Binary tarballs in https://releases.nixos.org/?prefix=nix/ -* Docker images +* Docker images (arm64 and amd64 variants, uploaded to DockerHub and GHCR) * Closures in https://cache.nixos.org From 29acca3ad64e74c52813db4e15f787d9cdb68a27 Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Tue, 30 Dec 2025 02:14:25 +0300 Subject: [PATCH 5/6] upload-release: Only upload the newly created tag (cherry picked from commit 3933e45d522f67328fd0756d75884df1ad368495) --- maintainers/upload-release.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maintainers/upload-release.pl b/maintainers/upload-release.pl index 19666590ed6..2bd99ded86e 100755 --- a/maintainers/upload-release.pl +++ b/maintainers/upload-release.pl @@ -324,7 +324,7 @@ sub downloadFile { chdir($opt->project_root) or die "Cannot chdir to " . $opt->project_root . ": $!"; system("git remote update origin") == 0 or die; system("git tag --force --sign $version $nixRev -m 'Tagging release $version'") == 0 or die; - system("git push --tags") == 0 or die; + system("git push origin refs/tags/$version") == 0 or die; system("git push --force-with-lease origin $nixRev:refs/heads/latest-release") == 0 or die if $isLatest; } From 544f8e24b076f21bfb850f4e6400e6be2d6b41a4 Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Tue, 30 Dec 2025 02:27:38 +0300 Subject: [PATCH 6/6] release-process: Document usage of upload-release.yml workflow (cherry picked from commit 84ff2ef34764abd643437096245042285fbcaf86) --- maintainers/release-process.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/maintainers/release-process.md b/maintainers/release-process.md index 3bc2379780e..8c76a57974d 100644 --- a/maintainers/release-process.md +++ b/maintainers/release-process.md @@ -104,21 +104,17 @@ release: evaluation ID (e.g. `1780832` in `https://hydra.nixos.org/eval/1780832`). -* Tag the release and upload the release artifacts to - [`releases.nixos.org`](https://releases.nixos.org/) and [Docker Hub](https://hub.docker.com/): +* Tag the release: ```console - $ IS_LATEST=1 ./maintainers/upload-release.pl + $ IS_LATEST=1 ./maintainers/upload-release.pl --skip-docker --skip-s3 --project-root $PWD ``` Note: `IS_LATEST=1` causes the `latest-release` branch to be force-updated. This is used by the `nixos.org` website to get the [latest Nix manual](https://nixos.org/manual/nixpkgs/unstable/). - TODO: This script requires the right AWS credentials. Document. - - TODO: This script currently requires a - `/home/eelco/Dev/nix-pristine`. +* Trigger the [`upload-release.yml` workflow](https://github.com/NixOS/nix/actions/workflows/upload-release.yml) via `workflow_dispatch` trigger. At the top click `Run workflow` -> select the current release branch from `Use workflow from` -> fill in `Hydra evaluation ID` with `` value from previous steps -> click `Run workflow`. Wait for the run to be approved by `NixOS/nix-team` (or bypass checks if warranted). Wait for the workflow to succeed. TODO: trigger nixos.org netlify: https://docs.netlify.com/configure-builds/build-hooks/ @@ -182,16 +178,18 @@ release: * Wait for the desired evaluation of the maintenance jobset to finish building. -* Run +* Tag the release ```console - $ IS_LATEST=1 ./maintainers/upload-release.pl + $ IS_LATEST=1 ./maintainers/upload-release.pl --skip-docker --skip-s3 --project-root $PWD ``` Omit `IS_LATEST=1` when creating a point release that is not on the most recent stable branch. This prevents `nixos.org` to going back to an older release. +* Trigger the [`upload-release.yml` workflow](https://github.com/NixOS/nix/actions/workflows/upload-release.yml) via `workflow_dispatch` trigger. At the top click `Run workflow` -> select the current release branch from `Use workflow from` -> fill in `Hydra evaluation ID` with `` value from previous steps -> click `Run workflow`. Wait for the run to be approved by `NixOS/nix-team` (or bypass checks if warranted). Wait for the workflow to succeed. + * Bump the version number of the release branch as above (e.g. to `2.12.2`).