diff --git a/src/repos/config.ts b/src/repos/config.ts index 211bd00..777e556 100644 --- a/src/repos/config.ts +++ b/src/repos/config.ts @@ -22,10 +22,12 @@ export interface RepoConfig { code?: string[]; docs?: string[]; }; + /** Override specific sparse paths to come from a different branch instead of the tag */ + sparsePathOverrides?: { paths: string[]; branch: string }[]; } /** Default Aztec version (tag) to use - can be overridden via AZTEC_DEFAULT_VERSION env var */ -export const DEFAULT_AZTEC_VERSION = process.env.AZTEC_DEFAULT_VERSION || "v3.0.0-devnet.6-patch.1"; +export const DEFAULT_AZTEC_VERSION = process.env.AZTEC_DEFAULT_VERSION || "v4.0.0-devnet.2-patch.1"; /** * Base Aztec repository configurations (without version) @@ -35,7 +37,7 @@ const BASE_REPOS: Omit[] = [ name: "aztec-packages", url: "https://github.com/AztecProtocol/aztec-packages", sparse: [ - "docs/docs", + "docs", "noir-projects/aztec-nr", "noir-projects/noir-contracts", "yarn-project", @@ -43,6 +45,16 @@ const BASE_REPOS: Omit[] = [ "boxes", "playground", ], + sparsePathOverrides: [ + { + paths: [ + "docs/developer_versioned_docs/version-{version}", + "docs/static/aztec-nr-api/devnet", + "docs/static/typescript-api/devnet", + ], + branch: "next", + }, + ], description: "Main Aztec monorepo - documentation, aztec-nr framework, and reference contracts", searchPatterns: { code: ["*.nr", "*.ts"], @@ -93,25 +105,23 @@ const BASE_REPOS: Omit[] = [ }, }, { - name: "aztec-otc-desk", - url: "https://github.com/aztec-pioneers/aztec-otc-desk", - branch: "main", - description: "Aztec OTC desk for peer-to-peer trading on Aztec", + name: "demo-wallet", + url: "https://github.com/AztecProtocol/demo-wallet", + description: "Aztec demo wallet application", searchPatterns: { code: ["*.nr", "*.ts"], docs: ["*.md"], }, }, { - name: "aztec-pay", - url: "https://github.com/aztec-pioneers/aztec-pay", - branch: "main", - description: "Aztec Pay - payment solution built on Aztec", + name: "gregoswap", + url: "https://github.com/AztecProtocol/gregoswap", + description: "Gregoswap - token swap application built on Aztec", searchPatterns: { code: ["*.nr", "*.ts"], docs: ["*.md"], }, - }, + } ]; /** @@ -125,6 +135,11 @@ export function getAztecRepos(version?: string): RepoConfig[] { ...repo, // Only apply version tag to Aztec repos, not Noir repos tag: repo.url.includes("AztecProtocol") ? tag : undefined, + // Resolve {version} placeholders in sparse path overrides + sparsePathOverrides: repo.sparsePathOverrides?.map((override) => ({ + ...override, + paths: override.paths.map((p) => p.replace("{version}", tag)), + })), })); } diff --git a/src/utils/git.ts b/src/utils/git.ts index f7f8d29..b12b050 100644 --- a/src/utils/git.ts +++ b/src/utils/git.ts @@ -90,6 +90,24 @@ export async function cloneRepo( await repoGit.raw(["sparse-checkout", "set", ...config.sparse]); await repoGit.fetch(["--depth=1", "origin", `refs/tags/${config.tag}:refs/tags/${config.tag}`]); await repoGit.checkout(config.tag); + + // Apply sparse path overrides from different branches + if (config.sparsePathOverrides) { + for (const override of config.sparsePathOverrides) { + await repoGit.fetch(["--depth=1", "origin", override.branch]); + try { + await repoGit.checkout([`origin/${override.branch}`, "--", ...override.paths]); + } catch (error) { + const repoBase = config.url.replace(/\.git$/, ""); + const parentDirs = [...new Set(override.paths.map((p) => p.split("/").slice(0, -1).join("/")))]; + const browseLinks = parentDirs.map((d) => `${repoBase}/tree/${override.branch}/${d}`); + throw new Error( + `sparsePathOverrides failed for branch "${override.branch}": could not checkout paths [${override.paths.join(", ")}]. ` + + `Check the actual folder names at: ${browseLinks.join(" , ")}`, + ); + } + } + } } else { await git.clone(config.url, repoPath, [ "--filter=blob:none", diff --git a/tests/repos/config.test.ts b/tests/repos/config.test.ts index 37bb522..e1169e3 100644 --- a/tests/repos/config.test.ts +++ b/tests/repos/config.test.ts @@ -26,6 +26,21 @@ describe("AZTEC_REPOS", () => { expect(noir!.sparse!.length).toBeGreaterThan(0); }); + it("aztec-packages has sparsePathOverrides for docs/docs on next branch", () => { + const ap = AZTEC_REPOS.find((r) => r.name === "aztec-packages"); + expect(ap?.sparse).toContain("docs"); + expect(ap?.sparsePathOverrides).toEqual([ + { + paths: [ + `docs/developer_versioned_docs/version-${DEFAULT_AZTEC_VERSION}`, + "docs/static/aztec-nr-api/devnet", + "docs/static/typescript-api/devnet", + ], + branch: "next", + }, + ]); + }); + it('noir and noir-examples have branch: "master"', () => { const noir = AZTEC_REPOS.find((r) => r.name === "noir"); const noirExamples = AZTEC_REPOS.find((r) => r.name === "noir-examples"); @@ -44,7 +59,7 @@ describe("getAztecRepos", () => { (r) => !r.url.includes("AztecProtocol") ); - expect(aztecProtocolRepos).toHaveLength(3); + expect(aztecProtocolRepos).toHaveLength(5); for (const repo of aztecProtocolRepos) { expect(repo.tag).toBe(DEFAULT_AZTEC_VERSION); } @@ -64,17 +79,13 @@ describe("getAztecRepos", () => { } }); - it("does not apply tags to noir-lang or aztec-pioneers repos", () => { + it("does not apply tags to noir-lang repos", () => { const repos = getAztecRepos("v2.0.0"); const noirRepos = repos.filter((r) => r.url.includes("noir-lang")); - const pioneerRepos = repos.filter((r) => - r.url.includes("aztec-pioneers") - ); expect(noirRepos).toHaveLength(2); - expect(pioneerRepos).toHaveLength(2); - for (const repo of [...noirRepos, ...pioneerRepos]) { + for (const repo of noirRepos) { expect(repo.tag).toBeUndefined(); } }); @@ -102,7 +113,7 @@ describe("getRepoNames", () => { expect(names).toContain("noir-examples"); expect(names).toContain("aztec-examples"); expect(names).toContain("aztec-starter"); - expect(names).toContain("aztec-otc-desk"); - expect(names).toContain("aztec-pay"); + expect(names).toContain("demo-wallet"); + expect(names).toContain("gregoswap"); }); }); diff --git a/tests/utils/git.test.ts b/tests/utils/git.test.ts index 8d45de0..8b79f89 100644 --- a/tests/utils/git.test.ts +++ b/tests/utils/git.test.ts @@ -146,6 +146,80 @@ describe("cloneRepo", () => { expect(mockGitInstance.checkout).toHaveBeenCalledWith("v1.0.0"); }); + it("sparse + tag + sparsePathOverrides: fetches override branch and checks out paths", async () => { + const overrideConfig: RepoConfig = { + ...sparseConfig, + sparsePathOverrides: [ + { + paths: [ + "docs/developer_versioned_docs/version-v1.0.0", + "docs/static/api", + ], + branch: "next", + }, + ], + }; + mockExistsSync.mockReturnValue(false); + mockGitInstance.clone.mockResolvedValue(undefined); + mockGitInstance.raw.mockResolvedValue(undefined); + mockGitInstance.fetch.mockResolvedValue(undefined); + mockGitInstance.checkout.mockResolvedValue(undefined); + + const result = await cloneRepo(overrideConfig); + expect(result).toContain("Cloned aztec-packages"); + + // Normal tag checkout happens first + expect(mockGitInstance.checkout).toHaveBeenCalledWith("v1.0.0"); + + // Then override: fetch the branch and checkout paths from it + expect(mockGitInstance.fetch).toHaveBeenCalledWith([ + "--depth=1", + "origin", + "next", + ]); + expect(mockGitInstance.checkout).toHaveBeenCalledWith([ + "origin/next", + "--", + "docs/developer_versioned_docs/version-v1.0.0", + "docs/static/api", + ]); + }); + + it("sparse + tag + sparsePathOverrides: throws descriptive error with GitHub links on failure", async () => { + const overrideConfig: RepoConfig = { + ...sparseConfig, + sparsePathOverrides: [ + { + paths: [ + "docs/developer_versioned_docs/version-v1.0.0", + "docs/static/aztec-nr-api/devnet", + "docs/static/typescript-api/devnet", + ], + branch: "next", + }, + ], + }; + mockExistsSync.mockReturnValue(false); + mockGitInstance.clone.mockResolvedValue(undefined); + mockGitInstance.raw.mockResolvedValue(undefined); + mockGitInstance.fetch.mockResolvedValue(undefined); + // Tag checkout succeeds, override checkout fails + mockGitInstance.checkout + .mockResolvedValueOnce(undefined) // tag checkout + .mockRejectedValueOnce(new Error("pathspec did not match")); + + try { + await cloneRepo(overrideConfig); + expect.unreachable("should have thrown"); + } catch (e: any) { + expect(e.message).toMatch(/sparsePathOverrides failed for branch "next"/); + expect(e.message).toContain("docs/developer_versioned_docs/version-v1.0.0"); + expect(e.message).toContain("https://github.com/AztecProtocol/aztec-packages/tree/next/docs/developer_versioned_docs"); + expect(e.message).toContain("https://github.com/AztecProtocol/aztec-packages/tree/next/docs/static/aztec-nr-api"); + expect(e.message).toContain("https://github.com/AztecProtocol/aztec-packages/tree/next/docs/static/typescript-api"); + } + }); + it("sparse + commit: clones with sparse flags, fetches commit", async () => { const commitConfig: RepoConfig = { ...sparseConfig,