diff --git a/flake.lock b/flake.lock index e97ceb6..67433af 100644 --- a/flake.lock +++ b/flake.lock @@ -43,17 +43,15 @@ ] }, "locked": { - "lastModified": 1716889250, - "narHash": "sha256-CkHMbl67d83o3FhABmMExK0lVvipGPxojSQZMN80tfY=", - "ref": "refs/heads/main", - "rev": "418e9937cbf8ba08557bf421d85b79bce69b3ca5", - "revCount": 2880, - "type": "git", - "url": "https://git.clan.lol/clan/clan-core" + "lastModified": 1716901339, + "narHash": "sha256-LGlFJ0+bydJdbvLLkfUx95mYMNHewyN3daq+UfhhRLs=", + "rev": "52584662a8b8217e11b6e057bcca1846b4cb2934", + "type": "tarball", + "url": "https://git.clan.lol/api/v1/repos/clan/clan-core/archive/52584662a8b8217e11b6e057bcca1846b4cb2934.tar.gz" }, "original": { - "type": "git", - "url": "https://git.clan.lol/clan/clan-core" + "type": "tarball", + "url": "https://git.clan.lol/clan/clan-core/archive/main.tar.gz" } }, "disko": { @@ -84,11 +82,11 @@ ] }, "locked": { - "lastModified": 1712014858, - "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", + "lastModified": 1715865404, + "narHash": "sha256-/GJvTdTpuDjNn84j82cU6bXztE0MSkdnTWClUCRub78=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", + "rev": "8dc45382d5206bd292f9c2768b8058a8fd8311d9", "type": "github" }, "original": { @@ -174,11 +172,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1714314149, - "narHash": "sha256-yNAevSKF4krRWacmLUsLK7D7PlfuY3zF0lYnGYNi9vQ=", + "lastModified": 1716715802, + "narHash": "sha256-usk0vE7VlxPX8jOavrtpOqphdfqEQpf9lgedlY/r66c=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "cf8cc1201be8bc71b7cbbbdaf349b22f4f99c7ae", + "rev": "e2dd4e18cc1c7314e24154331bae07df76eb582f", "type": "github" }, "original": { @@ -229,11 +227,11 @@ ] }, "locked": { - "lastModified": 1714444742, - "narHash": "sha256-FOWYXEEtwYKAGmXgKVYli/VsA8XpeR+4wNKt+3M/9b4=", + "lastModified": 1716771198, + "narHash": "sha256-vRDCDuFMvkvCjGT/N9K2lxG1E61vvq3TiU/4ZM36p8k=", "owner": "numtide", "repo": "srvos", - "rev": "b18e74f2245eaae150bc753821079c2512fe1516", + "rev": "5d4550de420ee501d7fa0e6cd9031cd00354554c", "type": "github" }, "original": { @@ -249,11 +247,11 @@ ] }, "locked": { - "lastModified": 1714058656, - "narHash": "sha256-Qv4RBm4LKuO4fNOfx9wl40W2rBbv5u5m+whxRYUMiaA=", + "lastModified": 1715940852, + "narHash": "sha256-wJqHMg/K6X3JGAE9YLM0LsuKrKb4XiBeVaoeMNlReZg=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "c6aaf729f34a36c445618580a9f95a48f5e4e03f", + "rev": "2fba33a182602b9d49f0b2440513e5ee091d838b", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index cca84d4..e576194 100644 --- a/flake.nix +++ b/flake.nix @@ -8,6 +8,7 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + flake-parts.url = "github:hercules-ci/flake-parts"; flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs"; treefmt-nix.url = "github:numtide/treefmt-nix"; @@ -17,7 +18,7 @@ # Use the version of nixpkgs that has been tested to work with SrvOS srvos.inputs.nixpkgs.follows = "nixpkgs"; - clan-core.url = "git+https://git.clan.lol/clan/clan-core"; + clan-core.url = "https://git.clan.lol/clan/clan-core/archive/main.tar.gz"; clan-core.inputs.flake-parts.follows = "flake-parts"; clan-core.inputs.nixpkgs.follows = "nixpkgs"; clan-core.inputs.treefmt-nix.follows = "treefmt-nix"; diff --git a/pkgs/gitea/0001-Add-an-immutable-tarball-link-to-archive-download-he.patch b/pkgs/gitea/0001-Add-an-immutable-tarball-link-to-archive-download-he.patch new file mode 100644 index 0000000..4594d0a --- /dev/null +++ b/pkgs/gitea/0001-Add-an-immutable-tarball-link-to-archive-download-he.patch @@ -0,0 +1,120 @@ +From dd2ccf4ff923757b81088e27e362e3fdb222c9d3 Mon Sep 17 00:00:00 2001 +From: Jade Lovelace +Date: Tue, 28 May 2024 16:36:25 +0200 +Subject: [PATCH] Add an immutable tarball link to archive download headers for + Nix +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This allows `nix flake metadata` and nix in general to lock a *branch* +tarball link in a manner that causes it to fetch the correct commit even +if the branch is updated with a newer version. + +For further context, Nix flakes are a feature that, among other things, +allows for "inputs" that are "github:someuser/somerepo", +"https://some-tarball-service/some-tarball.tar.gz", +"sourcehut:~meow/nya" or similar. This feature allows our users to fetch +tarballs of git-based inputs to their builds rather than using git to +fetch them, saving significant download time. + +There is presently no gitea or forgejo specific fetcher in Nix, and we +don't particularly wish to have one. Ideally (as a developer on a Nix +implementation myself) we could just use the generic tarball fetcher and +not add specific forgejo support, but to do so, we need additional +metadata to know which commit a given *branch* tarball represents, which +is the purpose of the Link header added here. + +The result of this patch is that a Nix user can specify `inputs.something.url = +"https://forgejo-host/some/project/archive/main.tar.gz"` in flake.nix +and get a link to some concrete tarball for the actual commit in the +lock file, then when they run `nix flake update` in the future, they +will get the latest commit in that branch. + +Example of it working locally: + + » nix flake metadata --refresh 'http://localhost:3000/api/v1/repos/jade/cats/archive/main.tar.gz?dir=configs/nix' +Resolved URL: http://localhost:3000/api/v1/repos/jade/cats/archive/main.tar.gz?dir=configs/nix +Locked URL: http://localhost:3000/api/v1/repos/jade/cats/archive/804ede182b6b66469b23ea4d21eece52766b7a06.tar.gz?dir=configs +/nix&narHash=sha256-yP7KkDVfuixZzs0fsqhSETXFC0y8m6nmPLw2GrAMxKQ%3D +Description: Computers with the nixos +Path: /nix/store/s856c6yqghyan4v0zy6jj19ksv0q22nx-source +Revision: 804ede182b6b66469b23ea4d21eece52766b7a06 +Last modified: 2024-05-02 00:48:32 + +For details on the header value, see: +https://github.com/nixos/nix/blob/56763ff918eb308db23080e560ed2ea3e00c80a7/doc/manual/src/protocols/tarball-fetcher.md + +Signed-off-by: Jörg Thalheim +--- + routers/api/v1/repo/file.go | 6 ++++++ + routers/web/repo/repo.go | 6 ++++++ + tests/integration/api_repo_archive_test.go | 11 +++++++++++ + 3 files changed, 23 insertions(+) + +diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go +index 156033f58a..b7ad63af08 100644 +--- a/routers/api/v1/repo/file.go ++++ b/routers/api/v1/repo/file.go +@@ -319,6 +319,12 @@ func archiveDownload(ctx *context.APIContext) { + func download(ctx *context.APIContext, archiveName string, archiver *repo_model.RepoArchiver) { + downloadName := ctx.Repo.Repository.Name + "-" + archiveName + ++ // Add nix format link header so tarballs lock correctly: ++ // https://github.com/nixos/nix/blob/56763ff918eb308db23080e560ed2ea3e00c80a7/doc/manual/src/protocols/tarball-fetcher.md ++ ctx.Resp.Header().Add("Link", fmt.Sprintf("<%s/archive/%s.tar.gz?rev=%s>; rel=\"immutable\"", ++ ctx.Repo.Repository.APIURL(), ++ archiver.CommitID, archiver.CommitID)) ++ + rPath := archiver.RelativePath() + if setting.RepoArchive.Storage.MinioConfig.ServeDirect { + // If we have a signed url (S3, object storage), redirect to this directly. +diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go +index 71c582b5f9..bb6349658f 100644 +--- a/routers/web/repo/repo.go ++++ b/routers/web/repo/repo.go +@@ -484,6 +484,12 @@ func Download(ctx *context.Context) { + func download(ctx *context.Context, archiveName string, archiver *repo_model.RepoArchiver) { + downloadName := ctx.Repo.Repository.Name + "-" + archiveName + ++ // Add nix format link header so tarballs lock correctly: ++ // https://github.com/nixos/nix/blob/56763ff918eb308db23080e560ed2ea3e00c80a7/doc/manual/src/protocols/tarball-fetcher.md ++ ctx.Resp.Header().Add("Link", fmt.Sprintf("<%s/archive/%s.tar.gz?rev=%s>; rel=\"immutable\"", ++ ctx.Repo.Repository.APIURL(), ++ archiver.CommitID, archiver.CommitID)) ++ + rPath := archiver.RelativePath() + if setting.RepoArchive.Storage.MinioConfig.ServeDirect { + // If we have a signed url (S3, object storage), redirect to this directly. +diff --git a/tests/integration/api_repo_archive_test.go b/tests/integration/api_repo_archive_test.go +index 57d3abfe84..340ff03961 100644 +--- a/tests/integration/api_repo_archive_test.go ++++ b/tests/integration/api_repo_archive_test.go +@@ -8,6 +8,7 @@ + "io" + "net/http" + "net/url" ++ "regexp" + "testing" + + auth_model "code.gitea.io/gitea/models/auth" +@@ -39,6 +40,16 @@ func TestAPIDownloadArchive(t *testing.T) { + assert.NoError(t, err) + assert.Len(t, bs, 266) + ++ // Must return a link to a commit ID as the "immutable" archive link ++ linkHeaderRe := regexp.MustCompile(`<(?Phttps?://.*/api/v1/repos/user2/repo1/archive/[a-f0-9]+\.tar\.gz.*)>; rel="immutable"`) ++ m := linkHeaderRe.FindStringSubmatch(resp.Header().Get("Link")) ++ assert.NotEmpty(t, m[1]) ++ resp = MakeRequest(t, NewRequest(t, "GET", m[1]).AddTokenAuth(token), http.StatusOK) ++ bs2, err := io.ReadAll(resp.Body) ++ assert.NoError(t, err) ++ // The locked URL should give the same bytes as the non-locked one ++ assert.EqualValues(t, bs, bs2) ++ + link, _ = url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/archive/master.bundle", user2.Name, repo.Name)) + resp = MakeRequest(t, NewRequest(t, "GET", link.String()).AddTokenAuth(token), http.StatusOK) + bs, err = io.ReadAll(resp.Body) +-- +2.44.1 + diff --git a/pkgs/gitea/default.nix b/pkgs/gitea/default.nix index a9fbdfd..223b0d7 100644 --- a/pkgs/gitea/default.nix +++ b/pkgs/gitea/default.nix @@ -3,5 +3,6 @@ gitea.overrideAttrs (old: { patches = old.patches ++ [ ./0001-add-bot-check.patch + ./0001-Add-an-immutable-tarball-link-to-archive-download-he.patch ]; })