@theholocron/cli 3.5.0 → 3.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +32 -28
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +8 -1
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -2470,7 +2470,7 @@ function vaultProviderName(loader) {
|
|
|
2470
2470
|
}
|
|
2471
2471
|
//#endregion
|
|
2472
2472
|
//#region src/commands/dependabot.yml
|
|
2473
|
-
var dependabot_default = "
|
|
2473
|
+
var dependabot_default = "version: 2\nupdates:\n - package-ecosystem: npm\n directory: /\n schedule:\n interval: weekly\n groups:\n security-patches:\n applies-to: security-updates\n patterns:\n - \"*\"\n all-dependencies:\n update-types:\n - minor\n - patch\n\n - package-ecosystem: github-actions\n directory: /\n schedule:\n interval: weekly\n groups:\n all-actions:\n patterns:\n - \"*\"\n";
|
|
2474
2474
|
//#endregion
|
|
2475
2475
|
//#region src/commands/workflows/audit.yml
|
|
2476
2476
|
var audit_default$1 = "name: Audit\n\non: # yamllint disable-line rule:truthy\n push:\n branches: [main, alpha]\n pull_request:\n\npermissions:\n contents: read\n\njobs:\n audit:\n uses: theholocron/.github/.github/workflows/audit.yml@main\n secrets: inherit\n";
|
|
@@ -2484,6 +2484,9 @@ var codeql_default$1 = "name: CodeQL\n\non: # yamllint disable-line rule:truthy\
|
|
|
2484
2484
|
//#region src/commands/workflows/dependencies.yml
|
|
2485
2485
|
var dependencies_default$1 = "name: Dependencies\n\non: # yamllint disable-line rule:truthy\n pull_request:\n\npermissions:\n contents: write\n pull-requests: write\n\njobs:\n dependencies:\n uses: theholocron/.github/.github/workflows/dependencies.yml@main\n secrets: inherit\n";
|
|
2486
2486
|
//#endregion
|
|
2487
|
+
//#region src/commands/workflows/deploy-docs.yml
|
|
2488
|
+
var deploy_docs_default$1 = "name: Deploy Docs\n\non: # yamllint disable-line rule:truthy\n push:\n branches: [main]\n paths:\n - docs/**\n workflow_dispatch:\n\nconcurrency:\n group: pages\n cancel-in-progress: false\n\npermissions:\n contents: read\n pages: write\n id-token: write\n\njobs:\n deploy-docs:\n name: Deploy Docs\n uses: theholocron/.github/.github/workflows/deploy-docs.yml@main\n secrets: inherit\n";
|
|
2489
|
+
//#endregion
|
|
2487
2490
|
//#region src/commands/workflows/greetings.yml
|
|
2488
2491
|
var greetings_default$1 = "name: Greetings\n\non: # yamllint disable-line rule:truthy\n pull_request:\n issues:\n\npermissions:\n issues: write\n pull-requests: write\n\njobs:\n greetings:\n uses: theholocron/.github/.github/workflows/greetings.yml@main\n secrets: inherit\n";
|
|
2489
2492
|
//#endregion
|
|
@@ -2499,9 +2502,6 @@ var review_default$1 = "name: Review\n\non: # yamllint disable-line rule:truthy\
|
|
|
2499
2502
|
//#region src/commands/workflows/stale.yml
|
|
2500
2503
|
var stale_default$1 = "name: Stale\n\non: # yamllint disable-line rule:truthy\n schedule:\n - cron: \"30 1 * * *\"\n\npermissions:\n contents: write\n issues: write\n pull-requests: write\n\njobs:\n stale:\n uses: theholocron/.github/.github/workflows/stale.yml@main\n secrets: inherit\n";
|
|
2501
2504
|
//#endregion
|
|
2502
|
-
//#region src/commands/workflows/sync-github.yml
|
|
2503
|
-
var sync_github_default$1 = "name: Sync GitHub Templates\n\non: # yamllint disable-line rule:truthy\n push:\n branches: [main, alpha]\n paths:\n - packages/cli/src/templates/index.ts\n - packages/cli/src/commands/setup-workflows.ts\n\nconcurrency:\n group: sync-github-${{ github.ref }}\n cancel-in-progress: true\n\npermissions:\n contents: read\n\njobs:\n sync:\n name: Sync\n uses: theholocron/.github/.github/workflows/sync-github.yml@main\n with:\n secondary-repos: theholocron/.github-private\n secrets:\n HOLOCRON_SYNC_TOKEN: ${{ secrets.HOLOCRON_SYNC_TOKEN }}\n";
|
|
2504
|
-
//#endregion
|
|
2505
2505
|
//#region src/commands/workflows/test.yml
|
|
2506
2506
|
var test_default$1 = "name: Test\n\non: # yamllint disable-line rule:truthy\n push:\n branches: [main, alpha]\n pull_request:\n\nconcurrency:\n group: test-${{ github.ref }}\n cancel-in-progress: true\n\npermissions:\n contents: read\n id-token: write\n\njobs:\n test:\n name: Test\n uses: theholocron/.github/.github/workflows/test.yml@main\n secrets: inherit\n";
|
|
2507
2507
|
//#endregion
|
|
@@ -2531,7 +2531,7 @@ const WORKFLOW_TEMPLATES = {
|
|
|
2531
2531
|
dependencies: dependencies_default$1,
|
|
2532
2532
|
bookkeeping: bookkeeping_default$1,
|
|
2533
2533
|
audit: audit_default$1,
|
|
2534
|
-
"
|
|
2534
|
+
"deploy-docs": deploy_docs_default$1
|
|
2535
2535
|
};
|
|
2536
2536
|
const KNOWN_WORKFLOWS = new Set(Object.keys(WORKFLOW_TEMPLATES));
|
|
2537
2537
|
/**
|
|
@@ -2552,7 +2552,7 @@ const WORKFLOW_CHECK_CONTEXTS = {
|
|
|
2552
2552
|
* merging `with:` overrides into the jobs block.
|
|
2553
2553
|
*
|
|
2554
2554
|
* Two strategies are used depending on the template:
|
|
2555
|
-
* - Templates that already have a `with:` block (e.g. lint
|
|
2555
|
+
* - Templates that already have a `with:` block (e.g. lint):
|
|
2556
2556
|
* the override entries are merged in, replacing existing keys and appending
|
|
2557
2557
|
* new ones.
|
|
2558
2558
|
* - Templates that end with ` secrets: inherit`: a new `with:` block is
|
|
@@ -2560,13 +2560,19 @@ const WORKFLOW_CHECK_CONTEXTS = {
|
|
|
2560
2560
|
* If neither pattern matches the template, a warning is emitted and the
|
|
2561
2561
|
* base template is returned unchanged.
|
|
2562
2562
|
*/
|
|
2563
|
-
function generateThinCallerContent(name, withOverrides) {
|
|
2563
|
+
function generateThinCallerContent(name, withOverrides, additionalPaths) {
|
|
2564
2564
|
const base = WORKFLOW_TEMPLATES[name];
|
|
2565
2565
|
if (!base) return "";
|
|
2566
|
-
if (!withOverrides || Object.keys(withOverrides).length === 0) return base;
|
|
2567
2566
|
const fmt = (k, v) => ` ${k}: ${v === true ? "true" : v === false ? "false" : String(v)}`;
|
|
2567
|
+
let result = base;
|
|
2568
|
+
if (additionalPaths && additionalPaths.length > 0) {
|
|
2569
|
+
const pathsBlockRe = /( {4}paths:\n)((?:[ ]{6}- [^\n]+\n)+)/;
|
|
2570
|
+
const newEntries = additionalPaths.map((p) => ` - ${p}\n`).join("");
|
|
2571
|
+
result = result.replace(pathsBlockRe, (_, header, existing) => header + existing + newEntries);
|
|
2572
|
+
}
|
|
2573
|
+
if (!withOverrides || Object.keys(withOverrides).length === 0) return result;
|
|
2568
2574
|
const withBlockRe = /( {4}with:\n)((?:[ ]{6}[^\n]+\n)*)/;
|
|
2569
|
-
const existingMatch =
|
|
2575
|
+
const existingMatch = result.match(withBlockRe);
|
|
2570
2576
|
if (existingMatch) {
|
|
2571
2577
|
const existingEntries = new Map(existingMatch[2].split("\n").filter(Boolean).map((line) => {
|
|
2572
2578
|
const m = line.match(/^ {6}([^:]+):\s*(.*)/);
|
|
@@ -2574,12 +2580,12 @@ function generateThinCallerContent(name, withOverrides) {
|
|
|
2574
2580
|
}).filter((e) => e !== null));
|
|
2575
2581
|
for (const [k, v] of Object.entries(withOverrides)) existingEntries.set(k, v === true ? "true" : v === false ? "false" : String(v));
|
|
2576
2582
|
const merged = [...existingEntries.entries()].map(([k, v]) => ` ${k}: ${v}`).join("\n");
|
|
2577
|
-
return
|
|
2583
|
+
return result.replace(withBlockRe, ` with:\n${merged}\n`);
|
|
2578
2584
|
}
|
|
2579
2585
|
const withBlock = Object.entries(withOverrides).map(([k, v]) => fmt(k, v)).join("\n");
|
|
2580
|
-
const
|
|
2581
|
-
if (
|
|
2582
|
-
return
|
|
2586
|
+
const injected = result.replace(/ {4}secrets: inherit\n$/, ` with:\n${withBlock}\n secrets: inherit\n`);
|
|
2587
|
+
if (injected === result) console.warn(`[generateThinCallerContent] could not inject with: overrides into "${name}" template`);
|
|
2588
|
+
return injected;
|
|
2583
2589
|
}
|
|
2584
2590
|
//#endregion
|
|
2585
2591
|
//#region src/commands/setup.ts
|
|
@@ -3037,6 +3043,7 @@ async function runSetup(input) {
|
|
|
3037
3043
|
for (const entry of workflows) {
|
|
3038
3044
|
const name = typeof entry === "string" ? entry : entry.name;
|
|
3039
3045
|
const withOverrides = typeof entry === "object" ? entry.with : void 0;
|
|
3046
|
+
const additionalPaths = typeof entry === "object" ? entry.paths : void 0;
|
|
3040
3047
|
if (!KNOWN_WORKFLOWS.has(name)) {
|
|
3041
3048
|
steps.push({
|
|
3042
3049
|
capability: "source",
|
|
@@ -3048,7 +3055,7 @@ async function runSetup(input) {
|
|
|
3048
3055
|
continue;
|
|
3049
3056
|
}
|
|
3050
3057
|
steps.push(await runStep("source", `write workflow ${name}`, dryRun, async () => {
|
|
3051
|
-
await source.writeWorkflowFile(`${name}.yml`, workflowHeader() + generateThinCallerContent(name, withOverrides));
|
|
3058
|
+
await source.writeWorkflowFile(`${name}.yml`, workflowHeader() + generateThinCallerContent(name, withOverrides, additionalPaths));
|
|
3052
3059
|
}));
|
|
3053
3060
|
print(formatStep(steps[steps.length - 1]));
|
|
3054
3061
|
}
|
|
@@ -3063,7 +3070,7 @@ async function runSetup(input) {
|
|
|
3063
3070
|
if (loader.has("source") && effectivePreset !== "none") {
|
|
3064
3071
|
const source = loader.get("source");
|
|
3065
3072
|
steps.push(await runStep("source", "write .github/dependabot.yml", dryRun, async () => {
|
|
3066
|
-
await source.writeRepoFile(".github/dependabot.yml", dependabot_default);
|
|
3073
|
+
await source.writeRepoFile(".github/dependabot.yml", workflowHeader("packages/cli/src/commands/setup.ts") + dependabot_default);
|
|
3067
3074
|
}));
|
|
3068
3075
|
print(formatStep(steps[steps.length - 1]));
|
|
3069
3076
|
}
|
|
@@ -3892,6 +3899,9 @@ var codeql_default = "name: CodeQL\n\non: # yamllint disable-line rule:truthy\n
|
|
|
3892
3899
|
//#region src/templates/workflows/dependencies.yml
|
|
3893
3900
|
var dependencies_default = "name: Dependencies\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n secrets:\n merge-token:\n description: >\n Optional privileged token for auto-merge. Falls back to GITHUB_TOKEN.\n Required when branch protection enforces required reviews — GITHUB_TOKEN\n cannot approve its own PRs.\n required: false\n\njobs:\n dependabot:\n name: Update the dependencies\n permissions:\n contents: write\n pull-requests: write\n runs-on: ubuntu-latest\n timeout-minutes: 5\n concurrency:\n group: dependencies-${{ github.event.pull_request.number }}\n cancel-in-progress: true\n if: github.event.pull_request.user.login == 'dependabot[bot]'\n steps:\n - uses: dependabot/fetch-metadata@25dd0e34f4fe68f24cc83900b1fe3fe149efef98 # v3.1.0\n name: Fetch Dependabot metadata\n id: metadata\n\n - run: gh pr merge --auto --squash \"$PR_URL\"\n # --squash is intentional: repo protection sets allow_merge_commit: false,\n # so --merge would fail on any repo using the standard preset.\n name: Enable auto-merge for Dependabot PRs\n if: steps.metadata.outputs.update-type == 'version-update:semver-patch'\n env:\n PR_URL: ${{ github.event.pull_request.html_url }}\n GH_TOKEN: ${{ secrets.merge-token || github.token }}\n";
|
|
3894
3901
|
//#endregion
|
|
3902
|
+
//#region src/templates/workflows/deploy-docs.yml
|
|
3903
|
+
var deploy_docs_default = "name: Deploy Docs\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n name:\n description: Repo name prefix used to derive package names (<name>-docs, <name>-site)\n required: true\n type: string\n use-turbo:\n description: Build content packages with pnpm turbo build (default true)\n required: false\n type: boolean\n default: true\n\njobs:\n build:\n name: Build\n runs-on: ubuntu-latest\n permissions:\n contents: read\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - name: Build content packages\n if: ${{ inputs.use-turbo }}\n env:\n DOCS_NAME: ${{ inputs.name }}\n run: pnpm turbo build --filter=@theholocron/\"$DOCS_NAME\"-docs\n\n - name: Build content packages\n if: ${{ !inputs.use-turbo }}\n env:\n DOCS_NAME: ${{ inputs.name }}\n run: pnpm --filter @theholocron/\"$DOCS_NAME\"-docs build\n\n - name: Build docs site\n env:\n DOCS_NAME: ${{ inputs.name }}\n run: pnpm --filter @theholocron/\"$DOCS_NAME\"-site build\n\n - uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3.0.1\n name: Upload pages artifact\n with:\n path: docs/dist\n\n deploy:\n name: Deploy\n needs: build\n runs-on: ubuntu-latest\n permissions:\n pages: write\n id-token: write\n environment:\n name: github-pages\n url: ${{ steps.deployment.outputs.page_url }}\n steps:\n - uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5\n id: deployment\n name: Deploy to GitHub Pages\n";
|
|
3904
|
+
//#endregion
|
|
3895
3905
|
//#region src/templates/workflows/greetings.yml
|
|
3896
3906
|
var greetings_default = "name: Greetings\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n\njobs:\n greeting:\n name: Greet first-time contributors\n permissions:\n issues: write\n pull-requests: write\n runs-on: ubuntu-latest\n timeout-minutes: 5\n # Group by the issue/PR number so duplicate events don't race each other.\n concurrency:\n group: greetings-${{ github.event.issue.number || github.event.pull_request.number }}\n cancel-in-progress: false\n steps:\n - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0\n name: Greet on first contribution\n with:\n script: |\n // Only greet on the initial open — ignore synchronize, reopened, etc.\n if (context.payload.action !== 'opened') return;\n\n const actor = context.actor;\n const { owner, repo } = context.repo;\n\n // Payload inspection is more reliable than context.eventName for detecting\n // whether this is an issue vs. PR event — works regardless of how GitHub\n // propagates event names through workflow_call chains.\n const isIssue = !!context.payload.issue && !context.payload.pull_request;\n // listForRepo returns both issues and PRs (GitHub treats PRs as issues),\n // sorted newest-first. Filter by type to track first-issue and first-PR\n // independently, and avoid search-index eventual-consistency lag.\n const { data: recent } = await github.rest.issues.listForRepo({\n owner, repo,\n creator: actor,\n state: 'all',\n per_page: 100\n });\n\n const sameType = recent.filter(item =>\n isIssue ? !item.pull_request : !!item.pull_request\n );\n\n if (sameType.length !== 1) return;\n const body = isIssue\n ? `Hey @${actor}!\\n\\nWe really appreciate you taking the time to report an issue. The collaborators on this project attempt to help as many people as possible, but we are a limited number of volunteers, so it is possible that this will not be addressed as swiftly.\\n\\nYour patience is much appreciated and we will get back to you as quickly as possible.`\n : `Hey @${actor}!\\n\\nWe really appreciate you taking the time to help out with this PR. The collaborators on this project attempt to help as many people as possible, but we are a limited number of volunteers, so it is possible that this will not be addressed as swiftly.\\n\\nYour patience is much appreciated and we will get back to you as quickly as possible.`;\n\n await github.rest.issues.createComment({\n owner,\n repo,\n issue_number: context.issue.number,\n body\n });\n";
|
|
3897
3907
|
//#endregion
|
|
@@ -3908,7 +3918,7 @@ var review_default = "name: Review\n\n# ReviewDog is the annotation layer — po
|
|
|
3908
3918
|
var stale_default = "name: Stale\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n days-before-stale:\n description: Days of inactivity before an issue is marked stale\n type: number\n required: false\n default: 30\n days-before-close:\n description: Days of inactivity after stale label before closing\n type: number\n required: false\n default: 5\n\njobs:\n stale:\n name: Mark stale issues and pull requests\n permissions:\n contents: write\n issues: write\n pull-requests: write\n runs-on: ubuntu-latest\n timeout-minutes: 10\n steps:\n - uses: actions/stale@1e223db275d687790206a7acac4d1a11bd6fe629 # v10.4.0\n name: Run Stale\n with:\n close-issue-message: >\n This issue was closed because it has been stalled for\n ${{ inputs.days-before-close }} days with no activity.\n days-before-close: ${{ inputs.days-before-close }}\n days-before-stale: ${{ inputs.days-before-stale }}\n exempt-all-pr-milestones: true\n stale-issue-label: wontfix\n stale-issue-message: >\n This issue is stale because it has been open ${{ inputs.days-before-stale }}\n days with no activity. Remove the stale label or comment, or this will be\n closed in ${{ inputs.days-before-close }} days.\n stale-pr-label: wontfix\n stale-pr-message: >\n This PR is stale because it has been open ${{ inputs.days-before-stale }}\n days with no activity. Remove the stale label or comment, or this will be\n closed in ${{ inputs.days-before-close }} days.\n";
|
|
3909
3919
|
//#endregion
|
|
3910
3920
|
//#region src/templates/workflows/sync-github.yml
|
|
3911
|
-
var sync_github_default = "name: Sync GitHub Templates\n\n# Builds the holocron CLI from source and pushes updated workflow templates\n# and composite actions to downstream .github repos. Runs whenever the\n# template source files change on main or alpha.\n#\n# Secrets required:\n# HOLOCRON_SYNC_TOKEN — fine-grained PAT (resource owner: org) with:\n# Contents: Read and write (git trees, blobs, refs)\n# Pull requests: Read and write (open sync PR)\n# Workflows: Read and write (write .github/workflows/*.yml)\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n primary-repo:\n description: >\n Primary .github repo — receives composite actions, reusable workflows,\n and thin-caller templates. Requires a PR (branch protection assumed).\n type: string\n required: false\n default: theholocron/.github\n secondary-repos:\n description: >\n Space-separated list of secondary repos (reusable workflows + thin\n callers only, no composite actions). Changes are delivered via pull\n request, same as the primary repo.\n type: string\n required: false\n default: \"\"\n sync-branch:\n description: Branch name used for the primary and secondary repo PRs\n type: string\n required: false\n default: chore/sync-templates\n secrets:\n HOLOCRON_SYNC_TOKEN:\n required: true\n HOLOCRON_READ_TOKEN:\n description: >\n Fine-grained PAT for read-only GitHub API calls (e.g. resolving git\n committer identity via `gh api user`). Falls back to HOLOCRON_SYNC_TOKEN.\n required: false\n GH_TOKEN:\n description: >\n Generic GitHub token fallback for `gh` CLI calls. Used when neither\n HOLOCRON_READ_TOKEN nor HOLOCRON_SYNC_TOKEN is set.\n required: false\n TURBO_TOKEN:\n required: false\n\njobs:\n sync:\n name: Sync templates\n runs-on: ubuntu-latest\n timeout-minutes: 15\n permissions:\n contents: read\n env:\n TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - run: pnpm build\n name: Build CLI\n\n - name: Cache actionlint\n id: cache-actionlint\n uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0\n with:\n path: /tmp/actionlint\n key: actionlint-v1.7.7-linux-amd64\n\n - name: Download actionlint\n if: steps.cache-actionlint.outputs.cache-hit != 'true'\n run: |\n curl -fsSL https://github.com/rhysd/actionlint/releases/download/v1.7.7/actionlint_1.7.7_linux_amd64.tar.gz \\\n | tar -xz -C /tmp actionlint\n\n - name: Validate generated workflows\n run: |\n node packages/cli/dist/cli.mjs sync-github \\\n --repo \"$PRIMARY_REPO\" \\\n --output-dir /tmp/sync-validate\n /tmp/actionlint /tmp/sync-validate/.github/workflows/*.yml\n env:\n PRIMARY_REPO: ${{ inputs.primary-repo }}\n\n - name: Sync primary repo (PR)\n run: |\n GIT_NAME=$(gh api user --jq .name 2>/dev/null || echo \"github-actions[bot]\")\n GIT_EMAIL=$(gh api user --jq '\"\\(.id)+\\(.login)@users.noreply.github.com\"' 2>/dev/null || echo \"41898282+github-actions[bot]@users.noreply.github.com\")\n COMMIT_MSG=\"chore: sync from theholocron/holocron\"$'\\n\\n'\"Signed-off-by: $GIT_NAME <$GIT_EMAIL>\"\n node packages/cli/dist/cli.mjs sync-github \\\n --repo \"$PRIMARY_REPO\" \\\n --branch \"$SYNC_BRANCH\" \\\n --pr \\\n --message \"$COMMIT_MSG\"\n env:\n GH_TOKEN: ${{ secrets.HOLOCRON_READ_TOKEN || secrets.HOLOCRON_SYNC_TOKEN || secrets.GH_TOKEN }}\n HOLOCRON_SYNC_TOKEN: ${{ secrets.HOLOCRON_SYNC_TOKEN }}\n PRIMARY_REPO: ${{ inputs.primary-repo }}\n SYNC_BRANCH: ${{ inputs.sync-branch }}\n\n - name: Sync secondary repos (PR)\n if: ${{ inputs.secondary-repos != '' }}\n run: |\n GIT_NAME=$(gh api user --jq .name 2>/dev/null || echo \"github-actions[bot]\")\n GIT_EMAIL=$(gh api user --jq '\"\\(.id)+\\(.login)@users.noreply.github.com\"' 2>/dev/null || echo \"41898282+github-actions[bot]@users.noreply.github.com\")\n COMMIT_MSG=\"chore: sync from theholocron/holocron\"$'\\n\\n'\"Signed-off-by: $GIT_NAME <$GIT_EMAIL>\"\n for repo in $SECONDARY_REPOS; do\n node packages/cli/dist/cli.mjs sync-github \\\n --repo \"$repo\" \\\n --branch \"$SYNC_BRANCH\" \\\n --pr \\\n --message \"$COMMIT_MSG\"\n done\n env:\n GH_TOKEN: ${{ secrets.HOLOCRON_READ_TOKEN || secrets.HOLOCRON_SYNC_TOKEN || secrets.GH_TOKEN }}\n HOLOCRON_SYNC_TOKEN: ${{ secrets.HOLOCRON_SYNC_TOKEN }}\n SECONDARY_REPOS: ${{ inputs.secondary-repos }}\n SYNC_BRANCH: ${{ inputs.sync-branch }}\n";
|
|
3921
|
+
var sync_github_default = "name: Sync GitHub Templates\n\n# Builds the holocron CLI from source and pushes updated workflow templates\n# and composite actions to downstream .github repos. Runs whenever the\n# template source files change on main or alpha.\n#\n# Secrets required:\n# HOLOCRON_SYNC_TOKEN — fine-grained PAT (resource owner: org) with:\n# Contents: Read and write (git trees, blobs, refs)\n# Pull requests: Read and write (open sync PR)\n# Workflows: Read and write (write .github/workflows/*.yml)\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n primary-repo:\n description: >\n Primary .github repo — receives composite actions, reusable workflows,\n and thin-caller templates. Requires a PR (branch protection assumed).\n type: string\n required: false\n default: theholocron/.github\n secondary-repos:\n description: >\n Space-separated list of secondary repos (reusable workflows + thin\n callers only, no composite actions). Changes are delivered via pull\n request, same as the primary repo.\n type: string\n required: false\n default: \"\"\n sync-branch:\n description: Branch name used for the primary and secondary repo PRs\n type: string\n required: false\n default: chore/sync-templates\n secrets:\n HOLOCRON_SYNC_TOKEN:\n required: true\n HOLOCRON_READ_TOKEN:\n description: >\n Fine-grained PAT for read-only GitHub API calls (e.g. resolving git\n committer identity via `gh api user`). Falls back to HOLOCRON_SYNC_TOKEN.\n required: false\n GH_TOKEN:\n description: >\n Generic GitHub token fallback for `gh` CLI calls. Used when neither\n HOLOCRON_READ_TOKEN nor HOLOCRON_SYNC_TOKEN is set.\n required: false\n TURBO_TOKEN:\n required: false\n\njobs:\n sync:\n name: Sync templates\n runs-on: ubuntu-latest\n timeout-minutes: 15\n permissions:\n contents: read\n env:\n TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - run: pnpm build\n name: Build CLI\n\n - name: Cache actionlint\n id: cache-actionlint\n uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0\n with:\n path: /tmp/actionlint\n key: actionlint-v1.7.7-linux-amd64\n\n - name: Download actionlint\n if: steps.cache-actionlint.outputs.cache-hit != 'true'\n run: |\n curl -fsSL https://github.com/rhysd/actionlint/releases/download/v1.7.7/actionlint_1.7.7_linux_amd64.tar.gz \\\n | tar -xz -C /tmp actionlint\n\n - name: Validate generated workflows\n run: |\n node packages/cli/dist/cli.mjs sync-github \\\n --repo \"$PRIMARY_REPO\" \\\n --output-dir /tmp/sync-validate\n /tmp/actionlint /tmp/sync-validate/.github/workflows/*.yml\n env:\n PRIMARY_REPO: ${{ inputs.primary-repo }}\n\n - name: Sync primary repo (PR)\n run: |\n GIT_NAME=$(gh api user --jq .name 2>/dev/null || echo \"github-actions[bot]\")\n GIT_EMAIL=$(gh api user --jq '\"\\(.id)+\\(.login)@users.noreply.github.com\"' 2>/dev/null || echo \"41898282+github-actions[bot]@users.noreply.github.com\")\n COMMIT_MSG=\"chore: sync from theholocron/holocron\"$'\\n\\n'\"Signed-off-by: $GIT_NAME <$GIT_EMAIL>\"\n node packages/cli/dist/cli.mjs sync-github \\\n --repo \"$PRIMARY_REPO\" \\\n --branch \"$SYNC_BRANCH\" \\\n --pr \\\n --message \"$COMMIT_MSG\"\n GH_TOKEN=\"$HOLOCRON_SYNC_TOKEN\" gh pr merge --auto --squash \\\n --repo \"$PRIMARY_REPO\" \"$SYNC_BRANCH\" 2>/dev/null || true\n env:\n GH_TOKEN: ${{ secrets.HOLOCRON_READ_TOKEN || secrets.HOLOCRON_SYNC_TOKEN || secrets.GH_TOKEN }}\n HOLOCRON_SYNC_TOKEN: ${{ secrets.HOLOCRON_SYNC_TOKEN }}\n PRIMARY_REPO: ${{ inputs.primary-repo }}\n SYNC_BRANCH: ${{ inputs.sync-branch }}\n\n - name: Sync secondary repos (PR)\n if: ${{ inputs.secondary-repos != '' }}\n run: |\n GIT_NAME=$(gh api user --jq .name 2>/dev/null || echo \"github-actions[bot]\")\n GIT_EMAIL=$(gh api user --jq '\"\\(.id)+\\(.login)@users.noreply.github.com\"' 2>/dev/null || echo \"41898282+github-actions[bot]@users.noreply.github.com\")\n COMMIT_MSG=\"chore: sync from theholocron/holocron\"$'\\n\\n'\"Signed-off-by: $GIT_NAME <$GIT_EMAIL>\"\n for repo in $SECONDARY_REPOS; do\n node packages/cli/dist/cli.mjs sync-github \\\n --repo \"$repo\" \\\n --branch \"$SYNC_BRANCH\" \\\n --pr \\\n --message \"$COMMIT_MSG\"\n GH_TOKEN=\"$HOLOCRON_SYNC_TOKEN\" gh pr merge --auto --squash \\\n --repo \"$repo\" \"$SYNC_BRANCH\" 2>/dev/null || true\n done\n env:\n GH_TOKEN: ${{ secrets.HOLOCRON_READ_TOKEN || secrets.HOLOCRON_SYNC_TOKEN || secrets.GH_TOKEN }}\n HOLOCRON_SYNC_TOKEN: ${{ secrets.HOLOCRON_SYNC_TOKEN }}\n SECONDARY_REPOS: ${{ inputs.secondary-repos }}\n SYNC_BRANCH: ${{ inputs.sync-branch }}\n";
|
|
3912
3922
|
//#endregion
|
|
3913
3923
|
//#region src/templates/workflows/test.yml
|
|
3914
3924
|
var test_default = "name: Test\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n secrets:\n TURBO_TOKEN:\n required: false\n\njobs:\n unit:\n name: Run tests and collect coverage\n permissions:\n contents: read\n id-token: write\n runs-on: ubuntu-latest\n timeout-minutes: 15\n env:\n TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - run: pnpm test -- --coverage\n name: Run tests with coverage\n\n - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0\n name: Upload coverage to Codecov\n with:\n use_oidc: true\n\n - uses: codecov/test-results-action@0fa95f0e1eeaafde2c782583b36b28ad0d8c77d3 # v1\n name: Upload test results to Codecov\n if: ${{ !cancelled() }}\n with:\n use_oidc: true\n files: '**/test-report.junit.xml'\n";
|
|
@@ -3935,6 +3945,7 @@ const REUSABLE_WORKFLOWS = {
|
|
|
3935
3945
|
bookkeeping: bookkeeping_default,
|
|
3936
3946
|
codeql: codeql_default,
|
|
3937
3947
|
dependencies: dependencies_default,
|
|
3948
|
+
"deploy-docs": deploy_docs_default,
|
|
3938
3949
|
greetings: greetings_default,
|
|
3939
3950
|
lint: lint_default,
|
|
3940
3951
|
release: release_default,
|
|
@@ -3944,18 +3955,11 @@ const REUSABLE_WORKFLOWS = {
|
|
|
3944
3955
|
test: test_default,
|
|
3945
3956
|
typecheck: typecheck_default
|
|
3946
3957
|
};
|
|
3947
|
-
const WORKFLOW_TEMPLATE_PROPERTIES = {
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
}, null, 2),
|
|
3953
|
-
"sync-github": JSON.stringify({
|
|
3954
|
-
name: "Sync GitHub Templates",
|
|
3955
|
-
description: "Sync workflow templates and composite actions from the holocron CLI.",
|
|
3956
|
-
iconName: "octicon sync"
|
|
3957
|
-
}, null, 2)
|
|
3958
|
-
};
|
|
3958
|
+
const WORKFLOW_TEMPLATE_PROPERTIES = { bookkeeping: JSON.stringify({
|
|
3959
|
+
name: "Bookkeeping",
|
|
3960
|
+
description: "Label and track issues and pull requests.",
|
|
3961
|
+
iconName: "octicon tag"
|
|
3962
|
+
}, null, 2) };
|
|
3959
3963
|
//#endregion
|
|
3960
3964
|
//#region src/commands/sync-github.ts
|
|
3961
3965
|
const DEFAULT_REPO = "theholocron/.github";
|