diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..a9112e9 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: 2026 LibreCode coop and contributors +# SPDX-License-Identifier: AGPL-3.0-or-later + +.github/workflows/** @vitormattos +.github/dependabot.yml @vitormattos +governance.config.json @vitormattos +action.yml @vitormattos +discover/action.yml @vitormattos +SECURITY.md @vitormattos +docs/** @vitormattos diff --git a/.github/workflows/typescript.yml b/.github/workflows/typescript.yml index 4c4b3e1..2cd6360 100644 --- a/.github/workflows/typescript.yml +++ b/.github/workflows/typescript.yml @@ -29,6 +29,23 @@ jobs: node-version: 24 package-manager-cache: false + - name: Verify native TypeScript action runtime + shell: bash + run: | + set +e + output="$(node src/cli.ts 2>&1)" + status=$? + set -e + test "$status" -eq 2 + grep -F "Specify exactly one of --org OWNER or --repo OWNER/REPO" <<< "$output" + + set +e + output="$(node src/discover-repositories.ts 2>&1)" + status=$? + set -e + test "$status" -eq 2 + grep -F "Usage: discover-repositories ORGANIZATION" <<< "$output" + - name: Install dependencies run: npm install --ignore-scripts diff --git a/action.yml b/action.yml index a7cd0f6..a66c55c 100644 --- a/action.yml +++ b/action.yml @@ -28,15 +28,6 @@ runs: node-version: 24 package-manager-cache: false - - name: Install governance dependencies - shell: bash - working-directory: ${{ github.action_path }} - run: npm install --ignore-scripts - - - name: Build governance CLI - shell: bash - working-directory: ${{ github.action_path }} - run: npm run build - name: Reconcile rulesets shell: bash @@ -56,4 +47,4 @@ runs: args+=(--apply) fi - node dist/cli.js "${args[@]}" + node src/cli.ts "${args[@]}" diff --git a/discover/action.yml b/discover/action.yml index c35da19..c333795 100644 --- a/discover/action.yml +++ b/discover/action.yml @@ -26,15 +26,6 @@ runs: node-version: 24 package-manager-cache: false - - name: Install governance dependencies - shell: bash - working-directory: ${{ github.action_path }}/.. - run: npm install --ignore-scripts - - - name: Build governance CLI - shell: bash - working-directory: ${{ github.action_path }}/.. - run: npm run build - name: Discover repositories id: discover @@ -44,5 +35,5 @@ runs: ORGANIZATION: ${{ inputs.organization }} working-directory: ${{ github.action_path }}/.. run: | - repositories="$(node dist/discover-repositories.js "$ORGANIZATION")" + repositories="$(node src/discover-repositories.ts "$ORGANIZATION")" echo "repositories=$repositories" >> "$GITHUB_OUTPUT" diff --git a/src/cli-runner.ts b/src/cli-runner.ts index 27c59c6..dd60c8e 100644 --- a/src/cli-runner.ts +++ b/src/cli-runner.ts @@ -5,14 +5,14 @@ import { loadGovernanceConfig, resolveRepositoryRulesets, type GovernanceConfig, -} from './config.js'; -import type { GovernanceClient } from './governance.js'; +} from './config.ts'; +import type { GovernanceClient } from './governance.ts'; import { planOrganization, planRepository, syncOrganization, syncRepository, -} from './governance.js'; +} from './governance.ts'; export type CliEnvironment = { GITHUB_TOKEN?: string | undefined; diff --git a/src/cli.ts b/src/cli.ts index 384fcb5..6aa6a7e 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -3,8 +3,8 @@ // SPDX-FileCopyrightText: 2026 LibreCode coop and contributors // SPDX-License-Identifier: AGPL-3.0-or-later -import { runCli } from './cli-runner.js'; -import { GitHubClient } from './github-client.js'; +import { runCli } from './cli-runner.ts'; +import { GitHubClient } from './github-client.ts'; const code = await runCli( process.argv.slice(2), diff --git a/src/config-validation.ts b/src/config-validation.ts index cf00119..ffcd266 100644 --- a/src/config-validation.ts +++ b/src/config-validation.ts @@ -5,12 +5,12 @@ import type { BypassActor, RepositoryRuleset, RulesetRule, -} from './types.js'; +} from './types.ts'; import type { ConditionalGovernanceConfig, GovernanceConfig, RepositoryGovernanceConfig, -} from './config.js'; +} from './config.ts'; export function validateGovernanceConfig(value: unknown): GovernanceConfig { const root = expectRecord(value, '$'); diff --git a/src/config.ts b/src/config.ts index 23c58a6..d82fb73 100644 --- a/src/config.ts +++ b/src/config.ts @@ -5,12 +5,12 @@ import { readFile } from 'node:fs/promises'; import type { BypassActor, RepositoryRuleset, -} from './types.js'; +} from './types.ts'; import type { GitHubContentProbe, RepositoryMetadata, -} from './repository-classifier.js'; -import { validateGovernanceConfig } from './config-validation.js'; +} from './repository-classifier.ts'; +import { validateGovernanceConfig } from './config-validation.ts'; export type RepositoryGovernanceConfig = { policies?: string[]; diff --git a/src/discover-repositories.ts b/src/discover-repositories.ts index 85c349e..8c7e4b9 100644 --- a/src/discover-repositories.ts +++ b/src/discover-repositories.ts @@ -3,7 +3,7 @@ // SPDX-FileCopyrightText: 2026 LibreCode coop and contributors // SPDX-License-Identifier: AGPL-3.0-or-later -import { discoverPublicRepositories } from './repository-discovery.js'; +import { discoverPublicRepositories } from './repository-discovery.ts'; const organization = process.argv[2]; diff --git a/src/github-client.ts b/src/github-client.ts index d0c47bf..ffdcd97 100644 --- a/src/github-client.ts +++ b/src/github-client.ts @@ -4,16 +4,16 @@ import type { RepositoryMetadata, GitHubContentProbe, -} from './repository-classifier.js'; +} from './repository-classifier.ts'; import type { ExistingRepositoryRuleset, RepositoryRulesetClient, -} from './ruleset-reconciler.js'; +} from './ruleset-reconciler.ts'; import type { BypassActor, RepositoryRuleset, RulesetRule, -} from './types.js'; +} from './types.ts'; type FetchLike = typeof fetch; @@ -34,11 +34,19 @@ type RulesetSummary = { export class GitHubClient implements GitHubContentProbe, RepositoryRulesetClient { + private readonly token: string; + private readonly fetchImpl: FetchLike; + private readonly apiUrl: string; + constructor( - private readonly token: string, - private readonly fetchImpl: FetchLike = fetch, - private readonly apiUrl = 'https://api.github.com', - ) {} + token: string, + fetchImpl: FetchLike = fetch, + apiUrl = 'https://api.github.com', + ) { + this.token = token; + this.fetchImpl = fetchImpl; + this.apiUrl = apiUrl; + } async getRepository( owner: string, diff --git a/src/governance.ts b/src/governance.ts index 175e6c8..3eec353 100644 --- a/src/governance.ts +++ b/src/governance.ts @@ -6,12 +6,12 @@ import { reconcileRepositoryRulesets, type RepositoryRulesetClient, type RulesetChange, -} from './ruleset-reconciler.js'; +} from './ruleset-reconciler.ts'; import type { GitHubContentProbe, RepositoryMetadata, -} from './repository-classifier.js'; -import type { RepositoryRuleset } from './types.js'; +} from './repository-classifier.ts'; +import type { RepositoryRuleset } from './types.ts'; export interface GovernanceClient extends GitHubContentProbe, diff --git a/src/ruleset-normalizer.ts b/src/ruleset-normalizer.ts index 7307ffa..c6f335f 100644 --- a/src/ruleset-normalizer.ts +++ b/src/ruleset-normalizer.ts @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: 2026 LibreCode coop and contributors // SPDX-License-Identifier: AGPL-3.0-or-later -import type { RepositoryRuleset, RulesetRule } from './types.js'; +import type { RepositoryRuleset, RulesetRule } from './types.ts'; function normalizeRule(rule: RulesetRule): RulesetRule { if (rule.type === 'pull_request') { diff --git a/src/ruleset-reconciler.ts b/src/ruleset-reconciler.ts index e75e57a..71f231f 100644 --- a/src/ruleset-reconciler.ts +++ b/src/ruleset-reconciler.ts @@ -1,8 +1,8 @@ // SPDX-FileCopyrightText: 2026 LibreCode coop and contributors // SPDX-License-Identifier: AGPL-3.0-or-later -import type { RepositoryRuleset } from './types.js'; -import { rulesetsEqual } from './ruleset-normalizer.js'; +import type { RepositoryRuleset } from './types.ts'; +import { rulesetsEqual } from './ruleset-normalizer.ts'; export type ExistingRepositoryRuleset = RepositoryRuleset & { id: number; diff --git a/src/validate-release.ts b/src/validate-release.ts index ea3814f..bdbb32c 100644 --- a/src/validate-release.ts +++ b/src/validate-release.ts @@ -5,7 +5,7 @@ import { execFileSync } from 'node:child_process'; import { readFile } from 'node:fs/promises'; -import { validateRelease } from './release-validator.js'; +import { validateRelease } from './release-validator.ts'; const requestedVersion = process.argv[2]; diff --git a/tsconfig.json b/tsconfig.json index 03b35e7..487400e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,8 @@ "skipLibCheck": true, "types": [ "node" - ] + ], + "rewriteRelativeImportExtensions": true }, "include": [ "src/**/*.ts",