diff --git a/config/repos.yaml b/config/repos.yaml index c4d21c4..9554753 100644 --- a/config/repos.yaml +++ b/config/repos.yaml @@ -36,6 +36,17 @@ repos: deleteBranchOnMerge: true autoInit: true + + - name: brand-assets + description: Shared Thaw brand assets — headers, icons, packaging art, marketing. + visibility: public + adopt: true + bare: true + hasIssues: false + hasWiki: false + hasProjects: false + hasDiscussions: false + - name: menubarspawner description: Small macOS menu-bar helper that spawns customizable status items. visibility: public diff --git a/config/rulesets.yaml b/config/rulesets.yaml index 18fa01f..3985e93 100644 --- a/config/rulesets.yaml +++ b/config/rulesets.yaml @@ -19,6 +19,11 @@ rulesets: refName: includes: - "~DEFAULT_BRANCH" + repositoryName: + includes: + - "~ALL" + excludes: + - brand-assets rules: creation: true update: false diff --git a/config/schema/repos.schema.json b/config/schema/repos.schema.json index 5c2f14d..c583407 100644 --- a/config/schema/repos.schema.json +++ b/config/schema/repos.schema.json @@ -159,6 +159,10 @@ "required": ["name"], "additionalProperties": false } + }, + "bare": { + "type": "boolean", + "description": "Adopt as a plain repo: no org labels, rulesets, CODEOWNERS, or implied team access." } }, "required": ["name", "description"], diff --git a/src/setup/resolve.ts b/src/setup/resolve.ts index fd13281..2d94370 100644 --- a/src/setup/resolve.ts +++ b/src/setup/resolve.ts @@ -106,16 +106,19 @@ export function buildRepoConfig( hasWiki: repo.hasWiki ?? features.wiki, hasProjects: repo.hasProjects ?? features.projects, hasDiscussions: repo.hasDiscussions ?? features.discussions, - labels: { ...labels, ...repo.labels }, + labels: repo.bare + ? { ...(repo.labels ?? {}) } + : { ...labels, ...repo.labels }, teams: teamAccess, - resolvedRepoRulesets: provisionRepoRulesets - ? rulesetsForRepo(repo.name, rulesets) - : [], + resolvedRepoRulesets: + repo.bare || !provisionRepoRulesets + ? [] + : rulesetsForRepo(repo.name, rulesets), resolvedBranchProtection, squashMergeCommitTitle: defaults.squashMergeCommitTitle, squashMergeCommitMessage: defaults.squashMergeCommitMessage, defaultBranch: defaults.defaultBranch, - codeownersContent: ctx.codeownersContent, + codeownersContent: repo.bare ? "" : ctx.codeownersContent, pulumiName: repo.pulumiName ?? repo.name, organization, }; diff --git a/src/types/repo.ts b/src/types/repo.ts index fa36d31..2111926 100644 --- a/src/types/repo.ts +++ b/src/types/repo.ts @@ -64,6 +64,7 @@ export const RepoConfigSchema = v.pipe( adopt: v.optional(v.boolean()), pulumiName: v.optional(v.string()), archived: v.optional(v.boolean()), + bare: v.optional(v.boolean()), hasIssues: v.optional(v.boolean()), hasWiki: v.optional(v.boolean()), hasProjects: v.optional(v.boolean()), diff --git a/test/resolve.test.ts b/test/resolve.test.ts index 88f834d..c9bbdd8 100644 --- a/test/resolve.test.ts +++ b/test/resolve.test.ts @@ -132,6 +132,42 @@ describe("buildRepoConfig", () => { ); expect(Object.keys(built.labels ?? {})).toEqual(["global", "local"]); }); + + it("bare repos skip org labels, rulesets, and CODEOWNERS", () => { + const built = buildRepoConfig(repo({ name: "brand-assets", bare: true }), { + ...baseCtx, + labels: { global: { color: "000000" } }, + provisionRepoRulesets: true, + rulesets: [ + { + id: "main-default", + target: "branch", + enforcement: "active", + conditions: { refName: { includes: ["~DEFAULT_BRANCH"] } }, + rules: { + creation: false, + update: false, + deletion: false, + nonFastForward: false, + requiredLinearHistory: false, + requiredSignatures: false, + copilotCodeReview: { + reviewDraftPullRequests: false, + reviewOnPush: false, + }, + pullRequest: {}, + requiredStatusChecks: { enabled: false }, + requiredCodeScanning: { enabled: false }, + mergeQueue: { enabled: false }, + requiredDeployments: { enabled: false }, + }, + }, + ], + }); + expect(built.labels).toEqual({}); + expect(built.resolvedRepoRulesets).toEqual([]); + expect(built.codeownersContent).toBe(""); + }); }); describe("resolveTeamAccess", () => {