@theholocron/cli 3.36.0 → 3.37.0
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 +60 -6
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -2844,11 +2844,11 @@ var typecheck_default$1 = "name: Typecheck\n\non: # yamllint disable-line rule:t
|
|
|
2844
2844
|
* @param source - path within theholocron/holocron that owns the template
|
|
2845
2845
|
* @param forPrimary - true only when writing to theholocron/.github itself
|
|
2846
2846
|
*/
|
|
2847
|
-
function workflowHeader(source = "packages/cli/src/commands/setup-workflows.ts", forPrimary = false) {
|
|
2847
|
+
function workflowHeader(source = "packages/cli/src/commands/setup-workflows.ts", forPrimary = false, tool = "holocron sync-github") {
|
|
2848
2848
|
return [
|
|
2849
2849
|
forPrimary ? `# AUTO-GENERATED — do not edit in theholocron/.github directly.` : `# AUTO-GENERATED — do not edit directly.`,
|
|
2850
2850
|
`# Source: theholocron/holocron · ${source}`,
|
|
2851
|
-
`# Tool:
|
|
2851
|
+
`# Tool: ${tool}`,
|
|
2852
2852
|
`# Changes: edit source in theholocron/holocron and push to alpha or main.`,
|
|
2853
2853
|
``
|
|
2854
2854
|
].join("\n");
|
|
@@ -4416,13 +4416,15 @@ const SYNC_STEPS = [
|
|
|
4416
4416
|
"keywords",
|
|
4417
4417
|
"description",
|
|
4418
4418
|
"homepage",
|
|
4419
|
-
"readme"
|
|
4419
|
+
"readme",
|
|
4420
|
+
"workflows"
|
|
4420
4421
|
];
|
|
4421
4422
|
const LOCAL_STEPS = /* @__PURE__ */ new Set([
|
|
4422
4423
|
"keywords",
|
|
4423
4424
|
"description",
|
|
4424
4425
|
"homepage",
|
|
4425
|
-
"readme"
|
|
4426
|
+
"readme",
|
|
4427
|
+
"workflows"
|
|
4426
4428
|
]);
|
|
4427
4429
|
async function runSync(input) {
|
|
4428
4430
|
const print = input.print ?? ((line) => console.log(line));
|
|
@@ -4561,7 +4563,8 @@ async function runSync(input) {
|
|
|
4561
4563
|
"keywords",
|
|
4562
4564
|
"description",
|
|
4563
4565
|
"homepage",
|
|
4564
|
-
"readme"
|
|
4566
|
+
"readme",
|
|
4567
|
+
"workflows"
|
|
4565
4568
|
]) {
|
|
4566
4569
|
if (requestedSteps !== void 0 && !requestedSteps.includes(stepName)) continue;
|
|
4567
4570
|
if (stepName === "keywords") {
|
|
@@ -4643,6 +4646,52 @@ async function runSync(input) {
|
|
|
4643
4646
|
});
|
|
4644
4647
|
print(formatSyncStep(steps[steps.length - 1]));
|
|
4645
4648
|
}
|
|
4649
|
+
if (stepName === "workflows") {
|
|
4650
|
+
const workflowEntries = config.workflows ?? [];
|
|
4651
|
+
if (workflowEntries.length === 0) {
|
|
4652
|
+
steps.push({
|
|
4653
|
+
capability: "local",
|
|
4654
|
+
step: "sync workflows",
|
|
4655
|
+
status: "skip",
|
|
4656
|
+
message: "no workflows configured"
|
|
4657
|
+
});
|
|
4658
|
+
print(formatSyncStep(steps[steps.length - 1]));
|
|
4659
|
+
} else for (const entry of workflowEntries) {
|
|
4660
|
+
const name = typeof entry === "string" ? entry : entry.name;
|
|
4661
|
+
const rawWith = typeof entry === "object" ? entry.with : void 0;
|
|
4662
|
+
const withOverrides = rawWith ? normalizeWorkflowWith(rawWith, config.name) : void 0;
|
|
4663
|
+
const additionalPaths = (typeof entry === "object" ? entry.paths : void 0) ?? (name === "deploy" && rawWith ? deriveDeployPaths(rawWith) : void 0);
|
|
4664
|
+
if (!KNOWN_WORKFLOWS.has(name)) {
|
|
4665
|
+
steps.push({
|
|
4666
|
+
capability: "local",
|
|
4667
|
+
step: `sync workflow ${name}`,
|
|
4668
|
+
status: "skip",
|
|
4669
|
+
message: `unknown workflow "${name}" — no template available`
|
|
4670
|
+
});
|
|
4671
|
+
print(formatSyncStep(steps[steps.length - 1]));
|
|
4672
|
+
continue;
|
|
4673
|
+
}
|
|
4674
|
+
if (name === "deploy" && rawWith) {
|
|
4675
|
+
const previewCfg = extractPreviewConfig(rawWith, {
|
|
4676
|
+
org: config.org,
|
|
4677
|
+
domain: config.domain
|
|
4678
|
+
});
|
|
4679
|
+
if (previewCfg) {
|
|
4680
|
+
steps.push(await runSyncStep("local", "sync workflow deploy (with preview)", dryRun, async () => {
|
|
4681
|
+
const content = workflowHeader() + generateCombinedDeployContent(withOverrides, additionalPaths, previewCfg);
|
|
4682
|
+
await writeWorkflowFile(input.context.repoRoot, "deploy.yml", content);
|
|
4683
|
+
}));
|
|
4684
|
+
print(formatSyncStep(steps[steps.length - 1]));
|
|
4685
|
+
continue;
|
|
4686
|
+
}
|
|
4687
|
+
}
|
|
4688
|
+
steps.push(await runSyncStep("local", `sync workflow ${name}`, dryRun, async () => {
|
|
4689
|
+
const content = workflowHeader() + generateThinCallerContent(name, withOverrides, additionalPaths);
|
|
4690
|
+
await writeWorkflowFile(input.context.repoRoot, `${name}.yml`, content);
|
|
4691
|
+
}));
|
|
4692
|
+
print(formatSyncStep(steps[steps.length - 1]));
|
|
4693
|
+
}
|
|
4694
|
+
}
|
|
4646
4695
|
}
|
|
4647
4696
|
const summary = steps.reduce((acc, s) => {
|
|
4648
4697
|
if (s.status === "ok") acc.ok += 1;
|
|
@@ -4730,6 +4779,11 @@ async function updateReadmeDescription(repoRoot, description) {
|
|
|
4730
4779
|
await writeFile(readmePath, lines.join("\n"), "utf8");
|
|
4731
4780
|
return true;
|
|
4732
4781
|
}
|
|
4782
|
+
async function writeWorkflowFile(repoRoot, filename, content) {
|
|
4783
|
+
const dir = join(repoRoot, ".github", "workflows");
|
|
4784
|
+
await mkdir(dir, { recursive: true });
|
|
4785
|
+
await writeFile(join(dir, filename), content, "utf8");
|
|
4786
|
+
}
|
|
4733
4787
|
//#endregion
|
|
4734
4788
|
//#region src/templates/actions/auto-commit.yml
|
|
4735
4789
|
var auto_commit_default = "name: Auto Commit\ndescription: >\n Commit and push any file changes using stefanzweifel/git-auto-commit-action.\n If a branch name is provided and differs from the current branch, a new branch\n is created automatically.\n\ninputs:\n token:\n description: >\n GitHub token with push access to the target branch. Used to authenticate\n the git remote so the commit can be pushed.\n required: true\n branch:\n description: >\n Branch to commit to. Leave empty to commit to the current branch (useful\n in PR contexts). Provide an explicit name (e.g. chore/auto-sync) to push\n to a separate branch.\n required: false\n default: \"\"\n commit-message:\n description: Commit message.\n required: true\n commit-options:\n description: >\n Additional options passed to git commit (e.g. --no-verify).\n required: false\n default: \"\"\n commit-user-name:\n description: Git user.name for the commit.\n required: false\n default: \"github-actions[bot]\"\n commit-user-email:\n description: Git user.email for the commit.\n required: false\n default: \"41898282+github-actions[bot]@users.noreply.github.com\"\n commit-author:\n description: >\n Git author string in \"Name <email>\" format.\n required: false\n default: \"github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>\"\n\noutputs:\n changes-detected:\n description: \"'true' if any files were committed, 'false' otherwise.\"\n value: ${{ steps.commit.outputs.changes_detected }}\n\nruns:\n using: composite\n steps:\n - name: Configure git remote with token\n shell: bash\n run: |\n REMOTE_URL=$(git remote get-url origin)\n AUTHED_URL=$(echo \"$REMOTE_URL\" | sed \"s|https://|https://x-access-token:${TOKEN}@|\")\n git remote set-url origin \"$AUTHED_URL\"\n env:\n TOKEN: ${{ inputs.token }}\n\n - name: Reset branch to current HEAD\n if: ${{ inputs.branch != '' }}\n shell: bash\n run: git checkout -B \"$BRANCH\"\n env:\n BRANCH: ${{ inputs.branch }}\n\n - uses: stefanzweifel/git-auto-commit-action@4a55954c782fc1ea30b9056cd3e7a2b40ca8887d # v7.2.0\n id: commit\n with:\n branch: ${{ inputs.branch }}\n commit_message: ${{ inputs.commit-message }}\n commit_options: ${{ inputs.commit-options }}\n commit_user_name: ${{ inputs.commit-user-name }}\n commit_user_email: ${{ inputs.commit-user-email }}\n commit_author: ${{ inputs.commit-author }}\n";
|
|
@@ -4783,7 +4837,7 @@ var review_default = "name: Review\n\n# ReviewDog is the annotation layer — po
|
|
|
4783
4837
|
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";
|
|
4784
4838
|
//#endregion
|
|
4785
4839
|
//#region src/templates/workflows/sync.yml
|
|
4786
|
-
var sync_default = "name: Sync\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n steps:\n description: >\n Sync steps to run (default: all). Valid values:\n labels, properties, teams, topics, keywords, description, homepage, readme.\n Pass a space-separated list to run a subset, e.g. \"readme\" or \"readme description\".\n type: string\n required: false\n secrets:\n HOLOCRON_ADMIN_TOKEN:\n description: Fine-grained PAT with admin scopes (labels, properties, teams).\n required: false\n HOLOCRON_DEPLOY_TOKEN:\n description: Fine-grained PAT for GitHub Pages configuration.\n required: false\n HOLOCRON_ISSUES_TOKEN:\n description: Fine-grained PAT for issue management.\n required: false\n HOLOCRON_ORG_TOKEN:\n description: Org-scoped fine-grained PAT for team sync and org properties.\n required: false\n HOLOCRON_READ_TOKEN:\n description: Fine-grained PAT for read-only GitHub API calls.\n required: false\n HOLOCRON_SYNC_TOKEN:\n required: false\n GH_TOKEN:\n description: >\n Generic GitHub token fallback for gh CLI calls. Used when\n HOLOCRON_SYNC_TOKEN is not set.\n required: false\n\njobs:\n sync:\n name: Sync repo from config\n runs-on: ubuntu-latest\n timeout-minutes: 10\n permissions:\n contents: write\n pull-requests: write\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n with:\n token: ${{ secrets.HOLOCRON_SYNC_TOKEN || secrets.GH_TOKEN || github.token }}\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - name: Run holocron sync\n run: |\n if [ -n \"$STEPS\" ]; then\n # shellcheck disable=SC2086\n pnpm exec holocron sync --steps $STEPS\n else\n pnpm exec holocron sync\n fi\n env:\n HOLOCRON_ADMIN_TOKEN: ${{ secrets.HOLOCRON_ADMIN_TOKEN }}\n HOLOCRON_DEPLOY_TOKEN: ${{ secrets.HOLOCRON_DEPLOY_TOKEN }}\n HOLOCRON_ISSUES_TOKEN: ${{ secrets.HOLOCRON_ISSUES_TOKEN }}\n HOLOCRON_ORG_TOKEN: ${{ secrets.HOLOCRON_ORG_TOKEN }}\n HOLOCRON_READ_TOKEN: ${{ secrets.HOLOCRON_READ_TOKEN }}\n HOLOCRON_SYNC_TOKEN: ${{ secrets.HOLOCRON_SYNC_TOKEN }}\n STEPS: ${{ inputs.steps }}\n\n - name: Format generated files\n run: pnpm exec prettier --write README.md docs/src/content/docs/index.mdx 2>/dev/null || true\n\n - uses: theholocron/.github/.github/actions/auto-commit@main\n id: auto-commit\n name: Commit sync changes\n with:\n token: ${{ secrets.HOLOCRON_SYNC_TOKEN || secrets.GH_TOKEN || github.token }}\n branch: chore/auto-sync\n commit-message: \"chore: sync from holocron.config\"\n commit-options: \"--no-verify\"\n\n - name: Open PR if changes were committed\n if: steps.auto-commit.outputs.changes-detected == 'true'\n run: |\n gh pr create \\\n --title \"chore: sync README and repo metadata\" \\\n --body \"Automated sync triggered by changes to config or package files. Merge to apply.\" \\\n --base main \\\n --head chore/auto-sync \\\n || echo \"PR already open — branch updated.\"\n env:\n GH_TOKEN: ${{ secrets.HOLOCRON_SYNC_TOKEN || secrets.GH_TOKEN || github.token }}\n";
|
|
4840
|
+
var sync_default = "name: Sync\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n steps:\n description: >\n Sync steps to run (default: all). Valid values:\n labels, properties, teams, topics, keywords, description, homepage, readme, workflows.\n Pass a space-separated list to run a subset, e.g. \"readme\" or \"readme description\".\n type: string\n required: false\n secrets:\n HOLOCRON_ADMIN_TOKEN:\n description: Fine-grained PAT with admin scopes (labels, properties, teams).\n required: false\n HOLOCRON_DEPLOY_TOKEN:\n description: Fine-grained PAT for GitHub Pages configuration.\n required: false\n HOLOCRON_ISSUES_TOKEN:\n description: Fine-grained PAT for issue management.\n required: false\n HOLOCRON_ORG_TOKEN:\n description: Org-scoped fine-grained PAT for team sync and org properties.\n required: false\n HOLOCRON_READ_TOKEN:\n description: Fine-grained PAT for read-only GitHub API calls.\n required: false\n HOLOCRON_SYNC_TOKEN:\n required: false\n GH_TOKEN:\n description: >\n Generic GitHub token fallback for gh CLI calls. Used when\n HOLOCRON_SYNC_TOKEN is not set.\n required: false\n\njobs:\n sync:\n name: Sync repo from config\n runs-on: ubuntu-latest\n timeout-minutes: 10\n permissions:\n contents: write\n pull-requests: write\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n with:\n token: ${{ secrets.HOLOCRON_SYNC_TOKEN || secrets.GH_TOKEN || github.token }}\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - name: Run holocron sync\n run: |\n if [ -n \"$STEPS\" ]; then\n # shellcheck disable=SC2086\n pnpm exec holocron sync --steps $STEPS\n else\n pnpm exec holocron sync\n fi\n env:\n HOLOCRON_ADMIN_TOKEN: ${{ secrets.HOLOCRON_ADMIN_TOKEN }}\n HOLOCRON_DEPLOY_TOKEN: ${{ secrets.HOLOCRON_DEPLOY_TOKEN }}\n HOLOCRON_ISSUES_TOKEN: ${{ secrets.HOLOCRON_ISSUES_TOKEN }}\n HOLOCRON_ORG_TOKEN: ${{ secrets.HOLOCRON_ORG_TOKEN }}\n HOLOCRON_READ_TOKEN: ${{ secrets.HOLOCRON_READ_TOKEN }}\n HOLOCRON_SYNC_TOKEN: ${{ secrets.HOLOCRON_SYNC_TOKEN }}\n STEPS: ${{ inputs.steps }}\n\n - name: Format generated files\n run: pnpm exec prettier --write README.md docs/src/content/docs/index.mdx 2>/dev/null || true\n\n - uses: theholocron/.github/.github/actions/auto-commit@main\n id: auto-commit\n name: Commit sync changes\n with:\n token: ${{ secrets.HOLOCRON_SYNC_TOKEN || secrets.GH_TOKEN || github.token }}\n branch: chore/auto-sync\n commit-message: \"chore: sync from holocron.config\"\n commit-options: \"--no-verify\"\n\n - name: Open PR if changes were committed\n if: steps.auto-commit.outputs.changes-detected == 'true'\n run: |\n gh pr create \\\n --title \"chore: sync README and repo metadata\" \\\n --body \"Automated sync triggered by changes to config or package files. Merge to apply.\" \\\n --base main \\\n --head chore/auto-sync \\\n || echo \"PR already open — branch updated.\"\n env:\n GH_TOKEN: ${{ secrets.HOLOCRON_SYNC_TOKEN || secrets.GH_TOKEN || github.token }}\n";
|
|
4787
4841
|
//#endregion
|
|
4788
4842
|
//#region src/templates/workflows/sync-broadcast.yml
|
|
4789
4843
|
var sync_broadcast_default = "name: Sync Broadcast\n\non: # yamllint disable-line rule:truthy\n workflow_dispatch:\n inputs:\n steps:\n description: >\n Sync steps to pass to each repo's sync.yml. Default is \"readme\"\n (only README marker blocks are updated).\n type: string\n required: false\n default: readme\n\npermissions:\n contents: read\n\njobs:\n broadcast:\n name: Broadcast sync to all repos\n runs-on: ubuntu-latest\n timeout-minutes: 15\n steps:\n - name: Dispatch sync to all repos with sync.yml\n run: |\n gh api /orgs/theholocron/repos --paginate --jq '.[].name' \\\n | while IFS= read -r repo; do\n gh api \"/repos/theholocron/$repo/contents/.github/workflows/sync.yml\" --silent 2>/dev/null || continue\n echo \"Dispatching sync to theholocron/$repo\"\n gh workflow run sync.yml \\\n --repo \"theholocron/$repo\" \\\n --field \"steps=$STEPS\"\n done\n env:\n GH_TOKEN: ${{ secrets.HOLOCRON_SYNC_TOKEN }}\n STEPS: ${{ inputs.steps }}\n";
|