@theholocron/astromech 5.0.0-alpha.178 → 5.0.0-alpha.179
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/index.mjs +5 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -121,6 +121,9 @@ var holocron_default = "name: Holocron\ndescription: >\n Run the Holocron CLI
|
|
|
121
121
|
//#region src/templates/reusable/actions/install.yml
|
|
122
122
|
var install_default = "name: Install dependencies\ndescription: Install project dependencies with pnpm frozen lockfile.\n\nruns:\n using: composite\n\n steps:\n - name: Install dependencies\n if: ${{ hashFiles('pnpm-lock.yaml') != '' }}\n shell: bash\n run: pnpm install --frozen-lockfile\n";
|
|
123
123
|
//#endregion
|
|
124
|
+
//#region src/templates/reusable/actions/notify.yml
|
|
125
|
+
var notify_default = "name: Notify\ndescription: >\n Post a message to a chat channel through an incoming webhook. The request\n body is Discord-compatible (`content`, `username`, `allowed_mentions`), so\n the webhook must accept that shape. Does nothing (and never fails the\n calling job) when no webhook is provided, so repos that haven't set one up\n are unaffected.\n\ninputs:\n webhook:\n description: >\n Incoming webhook URL for the target channel.\n A webhook posts to exactly one channel, so pass the secret for the\n channel this message belongs in (for example\n `secrets.HOLOCRON_NOTIFY_WEBHOOK_ALERTS`). Empty = skip.\n required: false\n default: \"\"\n message:\n description: Message text. Truncated to 2000 characters.\n required: true\n mention:\n description: >\n Optional role id (digits only) to ping. Only that one role can\n be mentioned; anything else in the message never pings.\n required: false\n default: \"\"\n username:\n description: Display name for the post.\n required: false\n default: \"Holocron\"\n\nruns:\n using: composite\n steps:\n - name: Post the notification\n shell: bash\n run: |\n if [ -z \"$WEBHOOK\" ]; then\n echo \"::notice::No notification webhook set — skipping notification.\"\n exit 0\n fi\n echo \"::add-mask::$WEBHOOK\"\n # allowed_mentions.parse = [] so message text can never ping @everyone\n # or a role; only the explicit `mention` role id is allowed through. The body is built with jq so quotes/newlines in the\n # message can't break the JSON.\n content=\"$MESSAGE\"\n roles='[]'\n if [[ \"$MENTION\" =~ ^[0-9]+$ ]]; then\n content=\"<@&$MENTION> $MESSAGE\"\n roles=$(jq -cn --arg r \"$MENTION\" '[$r]')\n fi\n body=$(jq -n --arg content \"${content:0:2000}\" --arg username \"$USERNAME\" --argjson roles \"$roles\" \\\n '{content: $content, username: $username, allowed_mentions: {parse: [], roles: $roles}}')\n status=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 15 \\\n -H 'Content-Type: application/json' -d \"$body\" \"$WEBHOOK\" || true)\n case \"${status:-000}\" in\n 2??) echo \"Notification posted.\" ;;\n *) echo \"::warning::Notification failed (HTTP ${status:-000}).\" ;;\n esac\n env:\n WEBHOOK: ${{ inputs.webhook }}\n MESSAGE: ${{ inputs.message }}\n MENTION: ${{ inputs.mention }}\n USERNAME: ${{ inputs.username }}\n";
|
|
126
|
+
//#endregion
|
|
124
127
|
//#region src/templates/reusable/actions/setup.yml
|
|
125
128
|
var setup_default = "name: Setup\ndescription: Prepare the environment and install project dependencies.\n\ninputs:\n node-version:\n description: Node.js version\n required: false\n default: \"22.x\"\n\nruns:\n using: composite\n\n steps:\n - uses: theholocron/.github/.github/actions/setup-node@main\n with:\n node-version: ${{ inputs.node-version }}\n\n - uses: theholocron/.github/.github/actions/install@main\n\n # `@theholocron/cli`'s `dist/cli.mjs` doesn't exist yet at this point, so\n # pnpm's workspace bin-linking can't create `node_modules/.bin/holocron`\n # (silent `WARN ... ENOENT`, not a hard failure). Every package whose\n # scripts delegate via `holocron run <task> --` then fails at run time\n # with `holocron: not found` (#698). Same fix the `holocron` composite\n # action already applies for its own direct invocation (see its \"Build\n # the workspace when the CLI resolves to an unbuilt checkout\" step) —\n # mirrored here so it also covers *nested* `holocron run <task> --`\n # calls from inside package.json scripts, which that action's own guard\n # doesn't reach. `pnpm build` (not a scoped `--filter`) so the CLI's own\n # workspace dependencies (e.g. astromech) build\n # in topological order too — a scoped build skips them and fails.\n # No-op in every consumer repo, where the published tarball already\n # ships `dist/`.\n - name: Build the Holocron CLI\n shell: bash\n run: |\n if [ ! -f node_modules/@theholocron/cli/dist/cli.mjs ]; then\n echo \"→ @theholocron/cli dist/ missing — building the workspace from source\" >&2\n pnpm build\n echo \"→ re-linking node_modules/.bin — pnpm skipped it pre-build\" >&2\n pnpm install --frozen-lockfile\n fi\n\n - name: Cache Turbo artifacts\n if: ${{ hashFiles('turbo.json') != '' }}\n uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0\n with:\n path: .turbo\n key: turbo-${{ runner.os }}-${{ github.sha }}\n restore-keys: |\n turbo-${{ runner.os }}-\n";
|
|
126
129
|
//#endregion
|
|
@@ -164,7 +167,7 @@ var platform_commitStandards_default$1 = "name: Commit Standards\n\non: # yamlli
|
|
|
164
167
|
var platform_dispatchedCheck_default = "name: Dispatched Check\n\non: # yamllint disable-line rule:truthy\n workflow_dispatch:\n inputs:\n repo:\n description: Target repo, \"owner/name\", to check out and run the task against.\n type: string\n required: true\n ref:\n description: Git ref (branch or commit SHA) to check out.\n type: string\n required: true\n task:\n description: The holocron task name to run (e.g. \"verification.typeSafety\").\n type: string\n required: true\n check-run-id:\n description: >\n ID of the check run already posted as \"queued\" on the target repo —\n patched to \"completed\" once the task finishes.\n type: string\n required: true\n\npermissions:\n contents: read\n\njobs:\n run-task:\n name: Run a Sentinel-dispatched task against another repo\n runs-on: ubuntu-latest\n timeout-minutes: 20\n env:\n TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n steps:\n # actions/create-github-app-token defaults to scoping its token to the\n # *current* repo (.github, where this workflow runs) when owner/\n # repositories are omitted — useless here, since every real use of this\n # token targets inputs.repo instead. Split \"owner/name\" up front so the\n # token step below can scope explicitly to the actual target.\n - name: Parse target repo\n id: target\n run: |\n echo \"owner=${INPUT_REPO%%/*}\" >> \"$GITHUB_OUTPUT\"\n echo \"name=${INPUT_REPO##*/}\" >> \"$GITHUB_OUTPUT\"\n env:\n INPUT_REPO: ${{ inputs.repo }}\n\n # Sentinel's own dispatch call only carries plain, non-secret inputs\n # (repo/ref/task/check-run-id — all visible in the Actions UI/logs).\n # This step mints a fresh, short-lived installation token here instead,\n # scoped by the same App's stored credentials — never a raw token\n # passed through a dispatch input.\n - name: Generate installation token\n id: app-token\n uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0\n with:\n app-id: ${{ secrets.SENTINEL_APP_ID }}\n private-key: ${{ secrets.SENTINEL_APP_PRIVATE_KEY }}\n owner: ${{ steps.target.outputs.owner }}\n repositories: ${{ steps.target.outputs.name }}\n\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout target repository\n with:\n repository: ${{ inputs.repo }}\n ref: ${{ inputs.ref }}\n token: ${{ steps.app-token.outputs.token }}\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - name: Run the task\n id: run-task\n continue-on-error: true\n uses: theholocron/.github/.github/actions/holocron@main\n with:\n task: ${{ inputs.task }}\n\n # A bare .../actions/runs/<id> link lands on the run summary, one click\n # short of the actual step-by-step log a normal check's details_url\n # points at. This job is always alone in its run, so the first (only)\n # job in the run's own job list is unambiguously this one.\n - name: Resolve this job's numeric ID\n id: job-info\n if: always()\n run: |\n job_id=$(gh api \"repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/jobs\" --jq '.jobs[0].id')\n echo \"job_id=$job_id\" >> \"$GITHUB_OUTPUT\"\n env:\n GH_TOKEN: ${{ steps.app-token.outputs.token }}\n\n # Ships the task's real captured output (tsc/vitest/etc — whatever\n # `holocron run` actually printed) to the same Axiom dataset Sentinel's\n # own structured logs already flow into, tagged so it's queryable by\n # this exact run. Reuses the existing dataset rather than provisioning\n # a new one — a prototype-stage call, revisit if CI-log volume ever\n # warrants a dedicated dataset. Builds a permalink filtered to this\n # run's own logs (Axiom's own \"copy query link\" URL shape:\n # /<org>/query?initForm={\"apl\":\"...\"} ) so a viewer lands directly on\n # the relevant lines, not a bare dataset view.\n - name: Ship task output to Axiom\n id: axiom\n if: always()\n run: |\n message=$(tail -c 40000 \"$LOG_FILE\" 2>/dev/null || echo \"(no output captured)\")\n # \"level\" is one of the field names Axiom's Stream/Query tabs\n # recognize for severity-color highlighting (docs: level, @level,\n # severity, @severity, status.code) -- conclusion alone isn't.\n level=$([ \"$CONCLUSION\" = \"success\" ] && echo \"info\" || echo \"error\")\n event=$(jq -cn \\\n --arg time \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\" \\\n --arg repo \"$REPO\" --arg task \"$TASK\" --arg run_id \"$GITHUB_RUN_ID\" \\\n --arg job_id \"$JOB_ID\" --arg check_run_id \"$CHECK_RUN_ID\" \\\n --arg conclusion \"$CONCLUSION\" --arg level \"$level\" --arg message \"$message\" \\\n '{_time: $time, source: \"dispatched-check\", repo: $repo, task: $task,\n run_id: $run_id, job_id: $job_id, check_run_id: $check_run_id,\n conclusion: $conclusion, level: $level, message: $message}')\n curl -sf -X POST \"https://api.axiom.co/v1/datasets/${AXIOM_DATASET}/ingest\" \\\n -H \"Authorization: Bearer ${AXIOM_TOKEN}\" \\\n -H \"Content-Type: application/json\" \\\n -d \"[${event}]\" || echo \"::warning::Axiom ingest failed — continuing, the check itself still reports the real result\"\n\n # The ['...'] is Axiom's own APL array-dataset-reference syntax, not\n # a shell quote boundary — $AXIOM_DATASET/$CHECK_RUN_ID both expand\n # fine here; shellcheck's single-quote heuristic just can't tell.\n # shellcheck disable=SC2016\n apl=\"['${AXIOM_DATASET}'] | where check_run_id == \\\"${CHECK_RUN_ID}\\\"\"\n init_form=$(jq -cn --arg apl \"$apl\" '{apl: $apl}')\n encoded=$(jq -rn --arg s \"$init_form\" '$s | @uri')\n echo \"query-url=https://app.axiom.co/${AXIOM_ORG}/query?initForm=${encoded}\" >> \"$GITHUB_OUTPUT\"\n env:\n LOG_FILE: ${{ steps.run-task.outputs.log-file }}\n REPO: ${{ inputs.repo }}\n TASK: ${{ inputs.task }}\n JOB_ID: ${{ steps.job-info.outputs.job_id }}\n CHECK_RUN_ID: ${{ inputs.check-run-id }}\n CONCLUSION: ${{ steps.run-task.outcome == 'success' && 'success' || 'failure' }}\n AXIOM_ORG: the-holocron-7bbe\n AXIOM_DATASET: holocron-sentinel\n AXIOM_TOKEN: ${{ secrets.SENTINEL_AXIOM_INGEST_TOKEN }}\n\n # Always runs, success or failure — the queued check run on the target\n # repo must be resolved either way, not left hanging. Full JSON body via\n # jq + --input, not -f flags: output.text needs real nesting (gh api -f\n # has no dot-notation for that), and the captured task output can\n # contain characters (quotes, $, backticks) that would break a\n # hand-built -f string.\n - name: Report result to the target repo's check run\n if: always()\n run: |\n excerpt=$(tail -c 3000 \"$LOG_FILE\" 2>/dev/null || echo \"(no output captured)\")\n # The single-quoted format string is intentional — every %s fills\n # via printf's own args below, not shell expansion; nothing in it\n # needs to expand.\n # shellcheck disable=SC2016\n text=$(printf '**Task:** `%s`\\n\\n**Result:** %s\\n\\n[Full logs on Axiom](%s)\\n\\n### Last output\\n\\n```\\n%s\\n```\\n' \\\n \"$TASK\" \"$CONCLUSION\" \"$QUERY_URL\" \"$excerpt\")\n body=$(jq -n \\\n --arg conclusion \"$CONCLUSION\" \\\n --arg details_url \"$RUN_URL\" \\\n --arg title \"$TASK ($CONCLUSION)\" \\\n --arg summary \"Dispatched via theholocron/.github — see the log excerpt below, or the full run/Axiom links.\" \\\n --arg text \"$text\" \\\n '{status: \"completed\", conclusion: $conclusion, details_url: $details_url,\n output: {title: $title, summary: $summary, text: $text}}')\n echo \"$body\" | gh api --method PATCH \"/repos/${REPO}/check-runs/${CHECK_RUN_ID}\" --input -\n env:\n # `GH_TOKEN` is the literal name `gh api` requires to auto-authenticate\n # -- not a stand-in for a shared/blanket credential. Its value is the\n # short-lived, Sentinel-App-scoped token minted above, same as the\n # checkout step uses; never secrets.HOLOCRON_SYNC_TOKEN (the one\n # genuinely shared PAT in this org, used by sync-dispatch.yml).\n GH_TOKEN: ${{ steps.app-token.outputs.token }}\n REPO: ${{ inputs.repo }}\n TASK: ${{ inputs.task }}\n CHECK_RUN_ID: ${{ inputs.check-run-id }}\n CONCLUSION: ${{ steps.run-task.outcome == 'success' && 'success' || 'failure' }}\n LOG_FILE: ${{ steps.run-task.outputs.log-file }}\n QUERY_URL: ${{ steps.axiom.outputs.query-url }}\n RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/job/${{ steps.job-info.outputs.job_id }}\n";
|
|
165
168
|
//#endregion
|
|
166
169
|
//#region src/templates/reusable/platform.repoSync.yml
|
|
167
|
-
var platform_repoSync_default$1 = "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, wiki.\n Pass a space-separated list to run a subset, e.g. \"readme\" or \"readme wiki\".\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_AXIOM_TOKEN:\n description: >\n Axiom API token. When set alongside the HOLOCRON_AXIOM_DATASET\n repo/org variable, the CLI ships this run's structured logs to Axiom.\n Falls back to the vendor-native AXIOM_TOKEN secret.\n required: false\n AXIOM_TOKEN:\n description: Vendor-native fallback for HOLOCRON_AXIOM_TOKEN.\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: Run holocron repo sync\n runs-on: ubuntu-latest\n timeout-minutes: 10\n # Serialise the find-or-create-PR and supersede steps repo-wide: the caller's\n # concurrency key is per ref, so runs from different refs could otherwise\n # interleave and leave several sync PRs open.\n concurrency:\n group: repo-sync-pr-${{ github.repository }}\n cancel-in-progress: false\n permissions:\n contents: write\n pull-requests: write\n # Job-level so the `holocron` composite action's steps inherit them.\n env:\n HOLOCRON_ADMIN_TOKEN: ${{ secrets.HOLOCRON_ADMIN_TOKEN }}\n HOLOCRON_AXIOM_TOKEN: ${{ secrets.HOLOCRON_AXIOM_TOKEN || secrets.AXIOM_TOKEN }}\n HOLOCRON_AXIOM_DATASET: ${{ vars.HOLOCRON_AXIOM_DATASET || vars.AXIOM_DATASET }}\n POSTHOG_PROJECT_TOKEN: ${{ vars.POSTHOG_PROJECT_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:\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 repo sync\n # The `holocron` action resolves @theholocron/cli from node_modules (or\n # builds the workspace when it's an unbuilt checkout — the holocron repo\n # itself). `inputs.steps` is a space-separated list or empty; the\n # `--steps <list>` arg is omitted when empty.\n uses: theholocron/.github/.github/actions/holocron@main\n with:\n command: repo sync\n args: ${{ inputs.steps != '' && format('--steps {0}', inputs.steps) || '' }}\n\n - name: Format generated files\n run: |\n pnpm exec prettier --write README.md docs/src/content/docs/index.mdx 2>/dev/null || true\n # `holocron repo sync` writes package.json fields (keywords, description,\n # homepage) with a plain assignment, which appends new keys at the\n # end — re-apply the canonical order the lint config enforces.\n pnpm exec eslint --fix --no-warn-ignored package.json 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 # One branch per source commit (full SHA, so distinct commits never collide): a PR left unreviewed never blocks the\n # next sync, and a re-run for the same commit updates its own branch.\n branch: ${{ format('chore/auto-sync-{0}', github.sha) }}\n commit-message: \"chore: sync from holocron.config\"\n commit-options: \"--no-verify\"\n\n - name: Open PR and enable auto-merge\n if: steps.auto-commit.outputs.changes-detected == 'true'\n run: |\n # Find or create this run's PR first: older PRs are only closed once\n # a replacement exists, so a failure here never leaves the changes\n # without an open PR.\n url=$(gh pr view \"$BRANCH\" --json url --jq .url 2>/dev/null || gh pr create \\\n --title \"chore: sync README and repo metadata\" \\\n --body \"Automated sync from holocron.config. Auto-merges once required checks pass.\" \\\n --base main \\\n --head \"$BRANCH\")\n created=$(gh pr view \"$url\" --json createdAt --jq .createdAt)\n\n # Supersede older sync PRs: same-repo only, exact generated or legacy\n # branch name, and created before this one (a slow older run can\n # never close a newer PR). --limit covers more than the default page.\n gh pr list --state open --limit 200 --json number,headRefName,isCrossRepository,createdAt \\\n --jq \".[] | select(.isCrossRepository | not) | select(.headRefName == \\\"chore/auto-sync\\\" or (.headRefName | test(\\\"^chore/auto-sync-[0-9a-f]{40}$\\\"))) | select(.headRefName != \\\"$BRANCH\\\") | select(.createdAt < \\\"$created\\\") | .number\" |\n while read -r n; do\n gh pr close \"$n\" --delete-branch --comment \"Superseded by $url.\" || true\n done\n\n # Delete pushed sync branches that never got a PR (e.g. a run\n # cancelled between push and PR creation). The repo-wide concurrency\n # group means no other run is mid-flight here.\n open=$(gh pr list --state open --limit 200 --json headRefName --jq '.[].headRefName')\n git ls-remote --heads origin 'refs/heads/chore/auto-sync-*' | sed 's|.*refs/heads/||' |\n while read -r b; do\n [ \"$b\" = \"$BRANCH\" ] && continue\n echo \"$b\" | grep -Eq '^chore/auto-sync-[0-9a-f]{40}$' || continue\n echo \"$open\" | grep -qxF \"$b\" || git push origin --delete \"$b\" || true\n done\n\n # A PR opened with the default GITHUB_TOKEN does not trigger\n # pull_request workflows, so required checks would never start and\n # auto-merge would wait forever.\n if [ \"$HAS_PAT\" != \"true\" ]; then\n echo \"::warning::Sync PR $url opened with GITHUB_TOKEN: checks will not run and auto-merge is skipped. Set HOLOCRON_SYNC_TOKEN.\"\n echo \"Sync PR $url — needs manual merge (no PAT).\" >> \"$GITHUB_STEP_SUMMARY\"\n elif gh pr merge \"$url\" --auto --squash; then\n echo \"Sync PR $url — auto-merge enabled.\" | tee -a \"$GITHUB_STEP_SUMMARY\"\n else\n echo \"::warning::Sync PR $url opened but auto-merge could not be enabled; merge it manually.\"\n echo \"Sync PR $url — needs manual merge.\" >> \"$GITHUB_STEP_SUMMARY\"\n fi\n env:\n BRANCH: ${{ format('chore/auto-sync-{0}', github.sha) }}\n HAS_PAT: ${{ secrets.HOLOCRON_SYNC_TOKEN != '' || secrets.GH_TOKEN != '' }}\n GH_TOKEN: ${{ secrets.HOLOCRON_SYNC_TOKEN || secrets.GH_TOKEN || github.token }}\n\n - name: Broadcast wiki sync if navbar changed\n if: >-\n steps.auto-commit.outputs.changes-detected == 'true' &&\n github.event_name == 'push' &&\n (inputs.steps == '' || contains(inputs.steps, 'wiki'))\n run: |\n if git diff HEAD~1 --name-only | grep -q 'fern/docs.yml'; then\n gh workflow run sync-dispatch.yml \\\n --repo theholocron/.github \\\n --field \"steps=wiki\" \\\n || echo \"skipping broadcast — insufficient permissions\"\n fi\n env:\n GH_TOKEN: ${{ secrets.HOLOCRON_SYNC_TOKEN || secrets.GH_TOKEN || github.token }}\n";
|
|
170
|
+
var platform_repoSync_default$1 = "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, wiki.\n Pass a space-separated list to run a subset, e.g. \"readme\" or \"readme wiki\".\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_AXIOM_TOKEN:\n description: >\n Axiom API token. When set alongside the HOLOCRON_AXIOM_DATASET\n repo/org variable, the CLI ships this run's structured logs to Axiom.\n Falls back to the vendor-native AXIOM_TOKEN secret.\n required: false\n AXIOM_TOKEN:\n description: Vendor-native fallback for HOLOCRON_AXIOM_TOKEN.\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 HOLOCRON_NOTIFY_WEBHOOK_SYNC:\n description: >\n Webhook for the sync channel: a sync PR opened and its\n auto-merge result. Unset = no post.\n required: false\n HOLOCRON_NOTIFY_WEBHOOK_ALERTS:\n description: >\n Webhook for the alerts channel: a failed sync run, or a sync\n PR that needs a manual merge. Unset = no post. An optional\n HOLOCRON_NOTIFY_ALERT_ROLE variable (a role id) makes\n these posts mention that role.\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: Run holocron repo sync\n runs-on: ubuntu-latest\n timeout-minutes: 10\n # Serialise the find-or-create-PR and supersede steps repo-wide: the caller's\n # concurrency key is per ref, so runs from different refs could otherwise\n # interleave and leave several sync PRs open.\n concurrency:\n group: repo-sync-pr-${{ github.repository }}\n cancel-in-progress: false\n permissions:\n contents: write\n pull-requests: write\n # Job-level so the `holocron` composite action's steps inherit them.\n env:\n HOLOCRON_ADMIN_TOKEN: ${{ secrets.HOLOCRON_ADMIN_TOKEN }}\n HOLOCRON_AXIOM_TOKEN: ${{ secrets.HOLOCRON_AXIOM_TOKEN || secrets.AXIOM_TOKEN }}\n HOLOCRON_AXIOM_DATASET: ${{ vars.HOLOCRON_AXIOM_DATASET || vars.AXIOM_DATASET }}\n POSTHOG_PROJECT_TOKEN: ${{ vars.POSTHOG_PROJECT_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:\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 repo sync\n # The `holocron` action resolves @theholocron/cli from node_modules (or\n # builds the workspace when it's an unbuilt checkout — the holocron repo\n # itself). `inputs.steps` is a space-separated list or empty; the\n # `--steps <list>` arg is omitted when empty.\n uses: theholocron/.github/.github/actions/holocron@main\n with:\n command: repo sync\n args: ${{ inputs.steps != '' && format('--steps {0}', inputs.steps) || '' }}\n\n - name: Format generated files\n run: |\n pnpm exec prettier --write README.md docs/src/content/docs/index.mdx 2>/dev/null || true\n # `holocron repo sync` writes package.json fields (keywords, description,\n # homepage) with a plain assignment, which appends new keys at the\n # end — re-apply the canonical order the lint config enforces.\n pnpm exec eslint --fix --no-warn-ignored package.json 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 # One branch per source commit (full SHA, so distinct commits never collide): a PR left unreviewed never blocks the\n # next sync, and a re-run for the same commit updates its own branch.\n branch: ${{ format('chore/auto-sync-{0}', github.sha) }}\n commit-message: \"chore: sync from holocron.config\"\n commit-options: \"--no-verify\"\n\n - name: Open PR and enable auto-merge\n id: pr\n if: steps.auto-commit.outputs.changes-detected == 'true'\n run: |\n # Find or create this run's PR first: older PRs are only closed once\n # a replacement exists, so a failure here never leaves the changes\n # without an open PR.\n url=$(gh pr view \"$BRANCH\" --json url --jq .url 2>/dev/null || gh pr create \\\n --title \"chore: sync README and repo metadata\" \\\n --body \"Automated sync from holocron.config. Auto-merges once required checks pass.\" \\\n --base main \\\n --head \"$BRANCH\")\n created=$(gh pr view \"$url\" --json createdAt --jq .createdAt)\n\n # Supersede older sync PRs: same-repo only, exact generated or legacy\n # branch name, and created before this one (a slow older run can\n # never close a newer PR). --limit covers more than the default page.\n gh pr list --state open --limit 200 --json number,headRefName,isCrossRepository,createdAt \\\n --jq \".[] | select(.isCrossRepository | not) | select(.headRefName == \\\"chore/auto-sync\\\" or (.headRefName | test(\\\"^chore/auto-sync-[0-9a-f]{40}$\\\"))) | select(.headRefName != \\\"$BRANCH\\\") | select(.createdAt < \\\"$created\\\") | .number\" |\n while read -r n; do\n gh pr close \"$n\" --delete-branch --comment \"Superseded by $url.\" || true\n done\n\n # Delete pushed sync branches that never got a PR (e.g. a run\n # cancelled between push and PR creation). The repo-wide concurrency\n # group means no other run is mid-flight here.\n open=$(gh pr list --state open --limit 200 --json headRefName --jq '.[].headRefName')\n git ls-remote --heads origin 'refs/heads/chore/auto-sync-*' | sed 's|.*refs/heads/||' |\n while read -r b; do\n [ \"$b\" = \"$BRANCH\" ] && continue\n echo \"$b\" | grep -Eq '^chore/auto-sync-[0-9a-f]{40}$' || continue\n echo \"$open\" | grep -qxF \"$b\" || git push origin --delete \"$b\" || true\n done\n\n # A PR opened with the default GITHUB_TOKEN does not trigger\n # pull_request workflows, so required checks would never start and\n # auto-merge would wait forever.\n if [ \"$HAS_PAT\" != \"true\" ]; then\n echo \"::warning::Sync PR $url opened with GITHUB_TOKEN: checks will not run and auto-merge is skipped. Set HOLOCRON_SYNC_TOKEN.\"\n echo \"Sync PR $url — needs manual merge (no PAT).\" >> \"$GITHUB_STEP_SUMMARY\"\n result=\"needs a manual merge (no PAT, so checks will not run)\"\n attention=true\n elif gh pr merge \"$url\" --auto --squash; then\n echo \"Sync PR $url — auto-merge enabled.\" | tee -a \"$GITHUB_STEP_SUMMARY\"\n result=\"auto-merge enabled\"\n else\n echo \"::warning::Sync PR $url opened but auto-merge could not be enabled; merge it manually.\"\n echo \"Sync PR $url — needs manual merge.\" >> \"$GITHUB_STEP_SUMMARY\"\n result=\"needs a manual merge (auto-merge could not be enabled)\"\n attention=true\n fi\n {\n echo \"url=$url\"\n echo \"result=$result\"\n echo \"attention=${attention:-false}\"\n } >> \"$GITHUB_OUTPUT\"\n env:\n BRANCH: ${{ format('chore/auto-sync-{0}', github.sha) }}\n HAS_PAT: ${{ secrets.HOLOCRON_SYNC_TOKEN != '' || secrets.GH_TOKEN != '' }}\n GH_TOKEN: ${{ secrets.HOLOCRON_SYNC_TOKEN || secrets.GH_TOKEN || github.token }}\n\n - uses: theholocron/.github/.github/actions/notify@main\n name: Notify of the sync PR\n if: steps.pr.outputs.url != '' && steps.pr.outputs.attention != 'true'\n with:\n webhook: ${{ secrets.HOLOCRON_NOTIFY_WEBHOOK_SYNC }}\n message: \"🔄 ${{ github.repository }}: sync PR ${{ steps.pr.outputs.url }} — ${{ steps.pr.outputs.result }}${{ github.run_attempt > 1 && format(' (attempt {0})', github.run_attempt) || '' }}\"\n\n - uses: theholocron/.github/.github/actions/notify@main\n name: Notify that a sync PR needs attention\n if: steps.pr.outputs.attention == 'true'\n with:\n webhook: ${{ secrets.HOLOCRON_NOTIFY_WEBHOOK_ALERTS }}\n mention: ${{ vars.HOLOCRON_NOTIFY_ALERT_ROLE }}\n message: \"⚠️ ${{ github.repository }}: sync PR ${{ steps.pr.outputs.url }} — ${{ steps.pr.outputs.result }}${{ github.run_attempt > 1 && format(' (attempt {0})', github.run_attempt) || '' }}\"\n\n - name: Broadcast wiki sync if navbar changed\n if: >-\n steps.auto-commit.outputs.changes-detected == 'true' &&\n github.event_name == 'push' &&\n (inputs.steps == '' || contains(inputs.steps, 'wiki'))\n run: |\n if git diff HEAD~1 --name-only | grep -q 'fern/docs.yml'; then\n gh workflow run sync-dispatch.yml \\\n --repo theholocron/.github \\\n --field \"steps=wiki\" \\\n || echo \"skipping broadcast — insufficient permissions\"\n fi\n env:\n GH_TOKEN: ${{ secrets.HOLOCRON_SYNC_TOKEN || secrets.GH_TOKEN || github.token }}\n\n # A separate job, not a final step: a job-level timeout cancels the sync job\n # before any later step in it can run, so an in-job `if: failure()` step would\n # stay silent on exactly the hang we most want to hear about. `!cancelled()` is\n # false when the whole run was cancelled (a newer run superseded this one), so\n # that expected case stays quiet, while a failed or timed-out sync job alerts.\n notify-failure:\n name: Notify of a failed sync\n needs: sync\n if: ${{ !cancelled() && (needs.sync.result == 'failure' || needs.sync.result == 'cancelled') }}\n runs-on: ubuntu-latest\n timeout-minutes: 2\n permissions: {}\n steps:\n - uses: theholocron/.github/.github/actions/notify@main\n name: Notify of a failed sync\n with:\n webhook: ${{ secrets.HOLOCRON_NOTIFY_WEBHOOK_ALERTS }}\n mention: ${{ vars.HOLOCRON_NOTIFY_ALERT_ROLE }}\n message: \"❌ ${{ github.repository }}: repo sync ${{ needs.sync.result == 'cancelled' && 'timed out or was cancelled' || 'failed' }} — ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}${{ github.run_attempt > 1 && format(' (attempt {0})', github.run_attempt) || '' }}\"\n";
|
|
168
171
|
//#endregion
|
|
169
172
|
//#region src/templates/reusable/platform.repoValidation.yml
|
|
170
173
|
var platform_repoValidation_default$1 = "name: Repo Validation\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n secrets:\n TURBO_TOKEN:\n required: false\n\njobs:\n adrs:\n name: Validate ADRs and specs\n permissions:\n contents: read\n runs-on: ubuntu-latest\n timeout-minutes: 10\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n with:\n fetch-depth: 0\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - uses: theholocron/.github/.github/actions/holocron@main\n name: Validate ADR and spec frontmatter\n with:\n task: platform.repoValidation\n job: adrs\n\n registry:\n name: Validate registry consistency\n permissions:\n contents: read\n runs-on: ubuntu-latest\n timeout-minutes: 10\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 - uses: theholocron/.github/.github/actions/holocron@main\n name: Validate registry consistency\n with:\n task: platform.repoValidation\n job: registry\n\n docs-presence:\n name: Validate docs presence\n permissions:\n contents: read\n runs-on: ubuntu-latest\n timeout-minutes: 10\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n with:\n fetch-depth: 0\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - uses: theholocron/.github/.github/actions/holocron@main\n name: Validate docs presence for new packages\n with:\n task: platform.repoValidation\n job: docsPresence\n env:\n BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}\n\n conclusion:\n name: Conclusion\n runs-on: ubuntu-latest\n if: always()\n needs: [adrs, registry, docs-presence]\n steps:\n - name: Check job statuses\n run: |\n if [[ \"$RESULTS\" == *\"failure\"* ]] || [[ \"$RESULTS\" == *\"cancelled\"* ]]; then\n exit 1\n fi\n env:\n RESULTS: ${{ join(needs.*.result, ',') }}\n";
|
|
@@ -557,6 +560,7 @@ const REUSABLE_ACTIONS = {
|
|
|
557
560
|
"auto-commit/action": auto_commit_default,
|
|
558
561
|
"holocron/action": holocron_default,
|
|
559
562
|
"install/action": install_default,
|
|
563
|
+
"notify/action": notify_default,
|
|
560
564
|
"setup/action": setup_default,
|
|
561
565
|
"setup-node/action": setup_node_default
|
|
562
566
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theholocron/astromech",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.179",
|
|
4
4
|
"description": "The Holocron task runner — one task manifest drives `holocron run`, `holocron run ci`, the CI workflows, package.json scripts, linters, and required checks.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ci",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"@theholocron/fs-utils": "^1.16.0",
|
|
49
49
|
"@theholocron/json-utils": "^1.16.0",
|
|
50
50
|
"@theholocron/pkg-utils": "^1.16.0",
|
|
51
|
-
"@theholocron/datapad": "5.0.0-alpha.
|
|
51
|
+
"@theholocron/datapad": "5.0.0-alpha.179"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@commitlint/config-conventional": "^21.2.3",
|