@theholocron/cli 2.0.0-alpha.63 → 2.0.0-alpha.65
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 +215 -1149
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -3,11 +3,13 @@ import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSy
|
|
|
3
3
|
import path, { basename, dirname, join } from "node:path";
|
|
4
4
|
import yargs from "yargs";
|
|
5
5
|
import { hideBin } from "yargs/helpers";
|
|
6
|
+
import { createInterface } from "node:readline";
|
|
7
|
+
import { stdin, stdout } from "node:process";
|
|
6
8
|
import { ProviderApiError, ProviderApiError as ProviderApiError$1 } from "@theholocron/http-client";
|
|
7
9
|
import { Entry, findCredentials } from "@napi-rs/keyring";
|
|
8
10
|
import { createHash } from "node:crypto";
|
|
9
11
|
import { createGitHubClient } from "@theholocron/github-client";
|
|
10
|
-
import { execFile, spawnSync } from "node:child_process";
|
|
12
|
+
import { execFile, execFileSync, spawnSync } from "node:child_process";
|
|
11
13
|
import { access, readFile, readdir, stat, writeFile } from "node:fs/promises";
|
|
12
14
|
import { pathToFileURL } from "node:url";
|
|
13
15
|
import { promisify } from "node:util";
|
|
@@ -834,879 +836,132 @@ async function runUpgradeNode(input) {
|
|
|
834
836
|
};
|
|
835
837
|
}
|
|
836
838
|
//#endregion
|
|
839
|
+
//#region src/templates/actions/setup.yml
|
|
840
|
+
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";
|
|
841
|
+
//#endregion
|
|
842
|
+
//#region src/templates/actions/install.yml
|
|
843
|
+
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";
|
|
844
|
+
//#endregion
|
|
845
|
+
//#region src/templates/actions/setup-node.yml
|
|
846
|
+
var setup_node_default = "name: Setup Node\ndescription: Install pnpm and Node.js with pnpm dependency caching.\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 - name: Setup pnpm\n if: ${{ hashFiles('pnpm-lock.yaml') != '' }}\n uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4\n\n - name: Setup Node.js\n uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4\n with:\n node-version: ${{ hashFiles('.node-version') != '' && '' || inputs.node-version }}\n node-version-file: ${{ hashFiles('.node-version') != '' && '.node-version' || '' }}\n cache: ${{ hashFiles('pnpm-lock.yaml') != '' && 'pnpm' || '' }}\n\n - name: Add node_modules/.bin to PATH\n shell: bash\n run: echo \"$GITHUB_WORKSPACE/node_modules/.bin\" >> $GITHUB_PATH\n";
|
|
847
|
+
//#endregion
|
|
848
|
+
//#region src/templates/workflows/audit.yml
|
|
849
|
+
var audit_default$1 = "name: Audit\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n build-script:\n description: Script to build and upload bundle stats to Codecov\n type: string\n required: false\n default: pnpm build\n secrets:\n CODECOV_TOKEN:\n required: false\n\njobs:\n bundle-size:\n name: Audit the bundle size\n permissions:\n contents: read\n runs-on: ubuntu-latest\n timeout-minutes: 15\n concurrency:\n group: audit-${{ github.ref }}\n cancel-in-progress: true\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 - run: eval \"$BUILD_SCRIPT\"\n name: Build and upload bundle stats\n env:\n BUILD_SCRIPT: ${{ inputs.build-script }}\n CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}\n";
|
|
850
|
+
//#endregion
|
|
851
|
+
//#region src/templates/workflows/bookkeeping.yml
|
|
852
|
+
var bookkeeping_default$1 = "name: Bookkeeping\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n configuration-path:\n description: Path to the labeler configuration file in the calling repo\n type: string\n required: false\n default: .github/labeler.yml\n\njobs:\n label:\n name: Apply Labels\n permissions:\n contents: read\n issues: write\n pull-requests: write\n runs-on: ubuntu-latest\n timeout-minutes: 5\n concurrency:\n group: bookkeeping-${{ github.event.pull_request.number || github.event.issue.number }}\n cancel-in-progress: true\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n with:\n sparse-checkout: ${{ inputs.configuration-path || '.github/labeler.yml' }}\n sparse-checkout-cone-mode: false\n\n - uses: github/issue-labeler@c1b0f9f52a63158c4adc09425e858e87b32e9685 # v3.4\n if: ${{ hashFiles(inputs.configuration-path || '.github/labeler.yml') != '' }}\n # v3.4 bundles Node 20; allow it to run under Actions' current default.\n env:\n ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true\n with:\n # Fall back to default path when triggered directly (not via workflow_call)\n # because inputs.* defaults only apply on workflow_call events.\n configuration-path: ${{ inputs.configuration-path || '.github/labeler.yml' }}\n include-title: 1\n include-body: 0\n sync-labels: 1\n enable-versioned-regex: 0\n repo-token: ${{ github.token }}\n";
|
|
853
|
+
//#endregion
|
|
854
|
+
//#region src/templates/workflows/codeql.yml
|
|
855
|
+
var codeql_default$1 = "name: CodeQL\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n language:\n description: CodeQL language to analyze\n type: string\n required: false\n default: javascript-typescript\n\njobs:\n analyze:\n name: Analyze (${{ inputs.language }})\n permissions:\n actions: read\n contents: read\n security-events: write\n runs-on: ubuntu-latest\n timeout-minutes: 45\n # Do not cancel in-progress security scans.\n concurrency:\n group: codeql-${{ github.ref }}\n cancel-in-progress: false\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n\n - uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0\n name: Initialize CodeQL\n with:\n languages: ${{ inputs.language }}\n\n - uses: github/codeql-action/autobuild@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0\n name: Autobuild\n\n - uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0\n name: Analyze\n with:\n category: /language:${{ inputs.language }}\n";
|
|
856
|
+
//#endregion
|
|
857
|
+
//#region src/templates/workflows/dependencies.yml
|
|
858
|
+
var dependencies_default$1 = "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";
|
|
859
|
+
//#endregion
|
|
860
|
+
//#region src/templates/workflows/greetings.yml
|
|
861
|
+
var greetings_default$1 = "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";
|
|
862
|
+
//#endregion
|
|
863
|
+
//#region src/templates/workflows/lint.yml
|
|
864
|
+
var lint_default$1 = "name: Lint\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n prettier-config:\n type: string\n required: false\n default: prettier.config.js\n yaml-config:\n type: string\n required: false\n default: yamllint.config.yml\n enable-auto-commit:\n description: Auto-commit super-linter fixes via GPG-signed commit\n type: boolean\n required: false\n default: false\n secrets:\n SUPER_LINTER_GPG_PRIVATE_KEY:\n required: false\n SUPER_LINTER_GPG_PASSPHRASE:\n required: false\n\njobs:\n super-lint:\n name: Lint entire codebase\n permissions:\n contents: write\n statuses: write\n runs-on: ubuntu-latest\n timeout-minutes: 30\n env:\n GPG_KEY_SET: ${{ secrets.SUPER_LINTER_GPG_PRIVATE_KEY != '' }}\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n with:\n fetch-depth: 0\n token: ${{ github.token }}\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n if: ${{ hashFiles('pnpm-lock.yaml') != '' }}\n\n - uses: super-linter/super-linter/slim@4ce20838b8ab83717e78138c5b3a1407148e0918 # v8.7.0\n name: Run Super Linter\n env:\n GITHUB_TOKEN: ${{ github.token }}\n DEFAULT_BRANCH: ${{ github.event.pull_request.base.ref || github.event.repository.default_branch }}\n ANNOTATE_ONLY: true\n DISABLE_COMMENTS: false\n IGNORE_GITIGNORED_FILES: true\n LINTER_RULES_PATH: /\n EDITORCONFIG_FILE_NAME: \".editorconfig-checker.json\"\n FIX_ENV: true\n FIX_GRAPHQL_PRETTIER: true\n FIX_HTML_PRETTIER: true\n FIX_JAVASCRIPT_PRETTIER: true\n FIX_JSX_PRETTIER: true\n FIX_MARKDOWN_PRETTIER: true\n FIX_TSX: true\n FIX_TYPESCRIPT_PRETTIER: true\n PRETTIER_CONFIG: ${{ inputs.prettier-config }}\n VALIDATE_DOCKERFILE: true\n VALIDATE_EDITORCONFIG: true\n VALIDATE_ENV: true\n VALIDATE_GIT_COMMITLINT: true\n VALIDATE_GIT_MERGE_CONFLICT_MARKERS: true\n VALIDATE_GITHUB_ACTIONS: true\n VALIDATE_GITLEAKS: true\n VALIDATE_GRAPHQL_PRETTIER: true\n VALIDATE_HTML_PRETTIER: true\n VALIDATE_JAVASCRIPT_PRETTIER: true\n VALIDATE_JSX_PRETTIER: true\n VALIDATE_MARKDOWN_PRETTIER: true\n VALIDATE_TSX: true\n VALIDATE_TYPESCRIPT_PRETTIER: true\n VALIDATE_YAML: true\n YAML_CONFIG_FILE: ${{ inputs.yaml-config }}\n\n - uses: crazy-max/ghaction-import-gpg@2dc316deee8e90f13e1a351ab510b4d5bc0c82cd # v7.0.0\n name: Import GPG Key\n # Conditions mirror auto-commit exactly — no point importing GPG if the\n # commit step will be skipped (fork PR, default branch, or secret unset).\n if: >\n inputs.enable-auto-commit == true &&\n github.event.pull_request != null &&\n github.event.pull_request.head.repo.full_name == github.repository &&\n github.ref_name != github.event.repository.default_branch &&\n env.GPG_KEY_SET == 'true'\n with:\n git_user_signingkey: true\n git_commit_gpgsign: true\n GPG_PRIVATE_KEY: ${{ secrets.SUPER_LINTER_GPG_PRIVATE_KEY }}\n PASSPHRASE: ${{ secrets.SUPER_LINTER_GPG_PASSPHRASE }}\n\n - uses: stefanzweifel/git-auto-commit-action@4a55954c782fc1ea30b9056cd3e7a2b40ca8887d # v7.2.0\n name: Commit and push linting fixes\n if: >\n inputs.enable-auto-commit == true &&\n github.event.pull_request != null &&\n github.event.pull_request.head.repo.full_name == github.repository &&\n github.ref_name != github.event.repository.default_branch &&\n env.GPG_KEY_SET == 'true'\n with:\n branch: ${{ github.event.pull_request.head.ref || github.head_ref || github.ref }}\n commit_message: \"chore: fix linting issues\\n\\nSigned-off-by: super-linter <super-linter@super-linter.dev>\"\n commit_options: \"--no-verify\"\n commit_user_name: super-linter\n commit_user_email: super-linter@super-linter.dev\n";
|
|
865
|
+
//#endregion
|
|
866
|
+
//#region src/templates/workflows/release.yml
|
|
867
|
+
var release_default$1 = "name: Release\n\n# Semantic-release with OIDC Trusted Publishing — no NPM_TOKEN required.\n# The calling repo must have a .releaserc.json that configures branches,\n# plugins, and any publish options. npm@11+ is installed to support OIDC.\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n run-build:\n description: Run `pnpm build` before releasing\n type: boolean\n required: false\n default: true\n secrets:\n SYNC_TOKEN:\n description: >\n Optional PAT with Contents write access. Required when the default\n branch is protected by a ruleset — github.token cannot push through\n rulesets, but a PAT with admin bypass can. Falls back to github.token.\n required: false\n\njobs:\n release:\n name: Semantic release\n permissions:\n contents: write\n id-token: write\n issues: write\n pull-requests: write\n runs-on: ubuntu-latest\n timeout-minutes: 30\n # Do not cancel in-progress releases — a partial release is worse than a slow one.\n concurrency:\n group: release-${{ github.ref }}\n cancel-in-progress: false\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n with:\n fetch-depth: 0\n # Use SYNC_TOKEN when available — git push (tags, release commits)\n # uses the checkout credential, not GITHUB_TOKEN env var. The\n # built-in github.token cannot push through branch protection rulesets.\n token: ${{ secrets.SYNC_TOKEN || github.token }}\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - name: Configure git identity\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 git config --global user.name \"$GIT_NAME\"\n git config --global user.email \"$GIT_EMAIL\"\n git config --global format.signoff true\n env:\n GH_TOKEN: ${{ secrets.SYNC_TOKEN || github.token }}\n\n - run: npm install -g npm@11 sigstore\n name: Upgrade npm for OIDC support\n # sigstore is required by libnpmpublish/provenance.js at module parse\n # time — before any config takes effect. Some npm 11.x builds stopped\n # bundling it; installing it globally into the same prefix ensures it\n # resolves regardless of npm version. (Discovered 2026-07-09.)\n\n - run: pnpm build\n name: Build\n if: ${{ inputs.run-build == true }}\n\n - run: npx semantic-release\n name: Release\n env:\n # Prefer SYNC_TOKEN (a PAT with Contents write) when available —\n # the built-in github.token cannot push to protected default branches\n # because rulesets block non-PAT pushes. Falls back to github.token\n # for repos without branch protection.\n GITHUB_TOKEN: ${{ secrets.SYNC_TOKEN || github.token }}\n NPM_CONFIG_PROVENANCE: true\n";
|
|
868
|
+
//#endregion
|
|
869
|
+
//#region src/templates/workflows/review.yml
|
|
870
|
+
var review_default$1 = "name: Review\n\n# ReviewDog is the annotation layer — posts inline PR diff annotations.\n# Runs on pull_request only: inline annotations require PR context,\n# and branch protection ensures all changes go through PRs anyway.\n# super-linter (lint.yml) is the CI gate covering push + PR events.\n# Gitleaks and YAML are intentionally duplicated: super-linter gates\n# merges; ReviewDog surfaces exact line annotations in the PR diff.\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n\nconcurrency:\n group: review-${{ github.workflow }}-${{ github.ref }}\n cancel-in-progress: true\n\njobs:\n reviewdog:\n name: Review PRs\n runs-on: ubuntu-latest\n timeout-minutes: 20\n permissions:\n contents: read\n checks: write\n pull-requests: write\n\n steps:\n - name: Checkout repository\n uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n with:\n fetch-depth: 0\n\n - name: Setup\n if: ${{ hashFiles('pnpm-lock.yaml') != '' }}\n uses: theholocron/.github/.github/actions/setup@main\n\n - name: Install ReviewDog\n uses: reviewdog/action-setup@d8a7baabd7f3e8544ee4dbde3ee41d0011c3a93f # v1\n with:\n reviewdog_version: latest\n\n # Detect which tools are relevant for this repo, excluding node_modules.\n # hashFiles('**/*') recurses into node_modules/.pnpm and produces false\n # positives for repos that don't own those file types.\n # -print -quit stops find after the first match without a pipe, avoiding\n # the SIGPIPE/pipefail exit-141 that find|head-1 triggers under\n # GitHub Actions' default bash --noprofile --norc -e -o pipefail mode.\n - name: Detect project features\n id: detect\n shell: bash\n run: |\n has() { find . -not -path '*/node_modules/*' -name \"$1\" -print -quit 2>/dev/null | grep -q .; }\n has_ext() { find . -not -path '*/node_modules/*' -name \"$1\" -print -quit 2>/dev/null | grep -q .; }\n { { has 'eslint.config.js' || has 'eslint.config.mjs' || has 'eslint.config.cjs' || \\\n has 'eslint.config.ts' || has '.eslintrc' || has '.eslintrc.js' || \\\n has '.eslintrc.cjs' || has '.eslintrc.json' || has '.eslintrc.yaml' || \\\n has '.eslintrc.yml'; } && grep -qF '\"eslint\":' package.json 2>/dev/null; } && echo \"eslint=true\" >> \"$GITHUB_OUTPUT\" || echo \"eslint=false\" >> \"$GITHUB_OUTPUT\"\n { has 'tsconfig.json' && grep -qF '\"typescript\":' package.json 2>/dev/null; } && echo \"tsconfig=true\" >> \"$GITHUB_OUTPUT\" || echo \"tsconfig=false\" >> \"$GITHUB_OUTPUT\"\n has_ext '*.sh' && echo \"shell=true\" >> \"$GITHUB_OUTPUT\" || echo \"shell=false\" >> \"$GITHUB_OUTPUT\"\n has 'Dockerfile' || has_ext '*.Dockerfile' || has 'Containerfile' && \\\n echo \"docker=true\" >> \"$GITHUB_OUTPUT\" || echo \"docker=false\" >> \"$GITHUB_OUTPUT\"\n has_ext '.env*' && echo \"dotenv=true\" >> \"$GITHUB_OUTPUT\" || echo \"dotenv=false\" >> \"$GITHUB_OUTPUT\"\n has_ext '*.md' && echo \"markdown=true\" >> \"$GITHUB_OUTPUT\" || echo \"markdown=false\" >> \"$GITHUB_OUTPUT\"\n\n #\n # Always applicable\n #\n\n - name: Gitleaks (secrets)\n uses: reviewdog/action-gitleaks@2b7b5685e3e3eecddab5d30cfa04f18123031421 # v1\n with:\n reporter: github-pr-check\n gitleaks_flags: --log-opts=${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}\n\n - name: YamlLint\n if: ${{ hashFiles('yamllint.config.yml') != '' }}\n uses: reviewdog/action-yamllint@b5f7217d8c815ae374d1d55840d5e569d82f01f0 # v1\n with:\n reporter: github-pr-check\n yamllint_flags: -c ${{ github.workspace }}/yamllint.config.yml ${{ github.workspace }}\n\n - name: ActionLint (GitHub Actions)\n if: ${{ hashFiles('.github/workflows/*.yml', '.github/workflows/*.yaml') != '' }}\n uses: reviewdog/action-actionlint@6fb7acc99f4a1008869fa8a0f09cfca740837d9d # v1\n with:\n reporter: github-pr-check\n\n #\n # TypeScript / JavaScript\n #\n\n - name: ESLint\n if: steps.detect.outputs.eslint == 'true'\n uses: reviewdog/action-eslint@556a3fdaf8b4201d4d74d406013386aa4f7dab96 # v1.34.0\n with:\n reporter: github-pr-check\n eslint_flags: .\n\n - name: TypeScript\n if: steps.detect.outputs.tsconfig == 'true'\n uses: EPMatt/reviewdog-action-tsc@63d923a3c5b4497671940b8874f58a404e2351b5 # v1\n with:\n reporter: github-pr-check\n\n #\n # Shell\n #\n\n - name: ShellCheck\n if: steps.detect.outputs.shell == 'true'\n uses: reviewdog/action-shellcheck@4c07458293ac342d477251099501a718ae5ef86e # v1\n with:\n reporter: github-pr-check\n fail_level: none\n\n #\n # Docker\n #\n\n - name: Hadolint\n if: steps.detect.outputs.docker == 'true'\n uses: reviewdog/action-hadolint@1b2cfa6ba72072ad35158d7ff3aa49bbdc03506d # v1\n with:\n reporter: github-pr-check\n fail_level: none\n\n #\n # Environment files\n #\n\n - name: dotenv-linter\n if: steps.detect.outputs.dotenv == 'true'\n uses: dotenv-linter/action-dotenv-linter@afde61cfda2ecffe7bea35837b6f20b956c88689 # v3.0.0\n with:\n reporter: github-code-suggestions\n\n #\n # Documentation\n #\n\n - name: Alex (inclusive language)\n if: steps.detect.outputs.markdown == 'true'\n uses: reviewdog/action-alex@347481655add010a2ae302df34b57c9bcfa0d6e4 # v1\n with:\n reporter: github-pr-check\n";
|
|
871
|
+
//#endregion
|
|
872
|
+
//#region src/templates/workflows/stale.yml
|
|
873
|
+
var stale_default$1 = "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";
|
|
874
|
+
//#endregion
|
|
875
|
+
//#region src/templates/workflows/sync-github.yml
|
|
876
|
+
var sync_github_default$1 = "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# 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 SYNC_TOKEN:\n required: true\n\njobs:\n sync:\n name: Sync templates\n runs-on: ubuntu-latest\n timeout-minutes: 15\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 - run: pnpm build\n name: Build CLI\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 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 /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 GITHUB_TOKEN: ${{ secrets.SYNC_TOKEN }}\n GH_TOKEN: ${{ secrets.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 GITHUB_TOKEN: ${{ secrets.SYNC_TOKEN }}\n GH_TOKEN: ${{ secrets.SYNC_TOKEN }}\n SECONDARY_REPOS: ${{ inputs.secondary-repos }}\n SYNC_BRANCH: ${{ inputs.sync-branch }}\n";
|
|
877
|
+
//#endregion
|
|
878
|
+
//#region src/templates/workflows/test.yml
|
|
879
|
+
var test_default$1 = "name: Test\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n secrets:\n CODECOV_TOKEN:\n required: false\n\njobs:\n unit:\n name: Run tests and collect coverage\n permissions:\n contents: read\n runs-on: ubuntu-latest\n timeout-minutes: 15\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 - 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 token: ${{ secrets.CODECOV_TOKEN }}\n\n - uses: codecov/test-results-action@0fa95f0e1eeaafde2c782583b36b28ad0d8c77d3 # v1\n name: Upload test results to Codecov\n if: ${{ !cancelled() }}\n with:\n token: ${{ secrets.CODECOV_TOKEN }}\n files: '**/test-report.junit.xml'\n";
|
|
880
|
+
//#endregion
|
|
881
|
+
//#region src/templates/workflows/typecheck.yml
|
|
882
|
+
var typecheck_default$1 = "name: Typecheck\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n\njobs:\n typecheck:\n name: tsc --noEmit\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 - run: pnpm typecheck\n name: Type check\n";
|
|
883
|
+
//#endregion
|
|
837
884
|
//#region src/templates/index.ts
|
|
838
885
|
/**
|
|
839
886
|
* All reusable workflow and composite action content bundled as string
|
|
840
887
|
* constants so the CLI can push them to theholocron/.github without
|
|
841
888
|
* needing filesystem access at runtime.
|
|
842
889
|
*
|
|
843
|
-
*
|
|
844
|
-
*
|
|
890
|
+
* Content lives in standalone .yml files; the rawYml rollup plugin
|
|
891
|
+
* inlines them as string exports at build time.
|
|
845
892
|
*/
|
|
846
893
|
const ACTIONS = {
|
|
847
|
-
"setup/action":
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
inputs:
|
|
852
|
-
node-version:
|
|
853
|
-
description: Node.js version
|
|
854
|
-
required: false
|
|
855
|
-
default: "22.x"
|
|
856
|
-
|
|
857
|
-
runs:
|
|
858
|
-
using: composite
|
|
859
|
-
|
|
860
|
-
steps:
|
|
861
|
-
- uses: theholocron/.github/.github/actions/setup-node@main
|
|
862
|
-
with:
|
|
863
|
-
node-version: \${{ inputs.node-version }}
|
|
864
|
-
|
|
865
|
-
- uses: theholocron/.github/.github/actions/install@main
|
|
866
|
-
`,
|
|
867
|
-
"install/action": `\
|
|
868
|
-
name: Install dependencies
|
|
869
|
-
description: Install project dependencies with pnpm frozen lockfile.
|
|
870
|
-
|
|
871
|
-
runs:
|
|
872
|
-
using: composite
|
|
873
|
-
|
|
874
|
-
steps:
|
|
875
|
-
- name: Install dependencies
|
|
876
|
-
if: \${{ hashFiles('pnpm-lock.yaml') != '' }}
|
|
877
|
-
shell: bash
|
|
878
|
-
run: pnpm install --frozen-lockfile
|
|
879
|
-
`,
|
|
880
|
-
"setup-node/action": `\
|
|
881
|
-
name: Setup Node
|
|
882
|
-
description: Install pnpm and Node.js with pnpm dependency caching.
|
|
883
|
-
|
|
884
|
-
inputs:
|
|
885
|
-
node-version:
|
|
886
|
-
description: Node.js version
|
|
887
|
-
required: false
|
|
888
|
-
default: "22.x"
|
|
889
|
-
|
|
890
|
-
runs:
|
|
891
|
-
using: composite
|
|
892
|
-
|
|
893
|
-
steps:
|
|
894
|
-
- name: Setup pnpm
|
|
895
|
-
if: \${{ hashFiles('pnpm-lock.yaml') != '' }}
|
|
896
|
-
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4
|
|
897
|
-
|
|
898
|
-
- name: Setup Node.js
|
|
899
|
-
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
|
900
|
-
with:
|
|
901
|
-
node-version: \${{ hashFiles('.node-version') != '' && '' || inputs.node-version }}
|
|
902
|
-
node-version-file: \${{ hashFiles('.node-version') != '' && '.node-version' || '' }}
|
|
903
|
-
cache: \${{ hashFiles('pnpm-lock.yaml') != '' && 'pnpm' || '' }}
|
|
904
|
-
|
|
905
|
-
- name: Add node_modules/.bin to PATH
|
|
906
|
-
shell: bash
|
|
907
|
-
run: echo "$GITHUB_WORKSPACE/node_modules/.bin" >> $GITHUB_PATH
|
|
908
|
-
`
|
|
894
|
+
"setup/action": setup_default,
|
|
895
|
+
"install/action": install_default,
|
|
896
|
+
"setup-node/action": setup_node_default
|
|
909
897
|
};
|
|
910
898
|
const REUSABLE_WORKFLOWS = {
|
|
911
|
-
audit:
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
cancel-in-progress: true
|
|
936
|
-
steps:
|
|
937
|
-
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
938
|
-
name: Checkout repository
|
|
939
|
-
with:
|
|
940
|
-
fetch-depth: 0
|
|
941
|
-
|
|
942
|
-
- uses: theholocron/.github/.github/actions/setup@main
|
|
943
|
-
name: Setup
|
|
944
|
-
|
|
945
|
-
- run: eval "$BUILD_SCRIPT"
|
|
946
|
-
name: Build and upload bundle stats
|
|
947
|
-
env:
|
|
948
|
-
BUILD_SCRIPT: \${{ inputs.build-script }}
|
|
949
|
-
CODECOV_TOKEN: \${{ secrets.CODECOV_TOKEN }}
|
|
950
|
-
`,
|
|
951
|
-
bookkeeping: `\
|
|
952
|
-
name: Bookkeeping
|
|
953
|
-
|
|
954
|
-
on: # yamllint disable-line rule:truthy
|
|
955
|
-
workflow_call:
|
|
956
|
-
inputs:
|
|
957
|
-
configuration-path:
|
|
958
|
-
description: Path to the labeler configuration file in the calling repo
|
|
959
|
-
type: string
|
|
960
|
-
required: false
|
|
961
|
-
default: .github/labeler.yml
|
|
962
|
-
|
|
963
|
-
jobs:
|
|
964
|
-
label:
|
|
965
|
-
name: Apply Labels
|
|
966
|
-
permissions:
|
|
967
|
-
contents: read
|
|
968
|
-
issues: write
|
|
969
|
-
pull-requests: write
|
|
970
|
-
runs-on: ubuntu-latest
|
|
971
|
-
timeout-minutes: 5
|
|
972
|
-
concurrency:
|
|
973
|
-
group: bookkeeping-\${{ github.event.pull_request.number || github.event.issue.number }}
|
|
974
|
-
cancel-in-progress: true
|
|
975
|
-
steps:
|
|
976
|
-
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
977
|
-
with:
|
|
978
|
-
sparse-checkout: \${{ inputs.configuration-path || '.github/labeler.yml' }}
|
|
979
|
-
sparse-checkout-cone-mode: false
|
|
980
|
-
|
|
981
|
-
- uses: github/issue-labeler@c1b0f9f52a63158c4adc09425e858e87b32e9685 # v3.4
|
|
982
|
-
if: \${{ hashFiles(inputs.configuration-path || '.github/labeler.yml') != '' }}
|
|
983
|
-
# v3.4 bundles Node 20; allow it to run under Actions' current default.
|
|
984
|
-
env:
|
|
985
|
-
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
|
986
|
-
with:
|
|
987
|
-
# Fall back to default path when triggered directly (not via workflow_call)
|
|
988
|
-
# because inputs.* defaults only apply on workflow_call events.
|
|
989
|
-
configuration-path: \${{ inputs.configuration-path || '.github/labeler.yml' }}
|
|
990
|
-
include-title: 1
|
|
991
|
-
include-body: 0
|
|
992
|
-
sync-labels: 1
|
|
993
|
-
enable-versioned-regex: 0
|
|
994
|
-
repo-token: \${{ github.token }}
|
|
995
|
-
`,
|
|
996
|
-
codeql: `\
|
|
997
|
-
name: CodeQL
|
|
998
|
-
|
|
999
|
-
on: # yamllint disable-line rule:truthy
|
|
1000
|
-
workflow_call:
|
|
1001
|
-
inputs:
|
|
1002
|
-
language:
|
|
1003
|
-
description: CodeQL language to analyze
|
|
1004
|
-
type: string
|
|
1005
|
-
required: false
|
|
1006
|
-
default: javascript-typescript
|
|
1007
|
-
|
|
1008
|
-
jobs:
|
|
1009
|
-
analyze:
|
|
1010
|
-
name: Analyze (\${{ inputs.language }})
|
|
1011
|
-
permissions:
|
|
1012
|
-
actions: read
|
|
1013
|
-
contents: read
|
|
1014
|
-
security-events: write
|
|
1015
|
-
runs-on: ubuntu-latest
|
|
1016
|
-
timeout-minutes: 45
|
|
1017
|
-
# Do not cancel in-progress security scans.
|
|
1018
|
-
concurrency:
|
|
1019
|
-
group: codeql-\${{ github.ref }}
|
|
1020
|
-
cancel-in-progress: false
|
|
1021
|
-
steps:
|
|
1022
|
-
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
1023
|
-
name: Checkout repository
|
|
1024
|
-
|
|
1025
|
-
- uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
|
|
1026
|
-
name: Initialize CodeQL
|
|
1027
|
-
with:
|
|
1028
|
-
languages: \${{ inputs.language }}
|
|
1029
|
-
|
|
1030
|
-
- uses: github/codeql-action/autobuild@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
|
|
1031
|
-
name: Autobuild
|
|
1032
|
-
|
|
1033
|
-
- uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
|
|
1034
|
-
name: Analyze
|
|
1035
|
-
with:
|
|
1036
|
-
category: /language:\${{ inputs.language }}
|
|
1037
|
-
`,
|
|
1038
|
-
dependencies: `\
|
|
1039
|
-
name: Dependencies
|
|
1040
|
-
|
|
1041
|
-
on: # yamllint disable-line rule:truthy
|
|
1042
|
-
workflow_call:
|
|
1043
|
-
secrets:
|
|
1044
|
-
merge-token:
|
|
1045
|
-
description: >
|
|
1046
|
-
Optional privileged token for auto-merge. Falls back to GITHUB_TOKEN.
|
|
1047
|
-
Required when branch protection enforces required reviews — GITHUB_TOKEN
|
|
1048
|
-
cannot approve its own PRs.
|
|
1049
|
-
required: false
|
|
1050
|
-
|
|
1051
|
-
jobs:
|
|
1052
|
-
dependabot:
|
|
1053
|
-
name: Update the dependencies
|
|
1054
|
-
permissions:
|
|
1055
|
-
contents: write
|
|
1056
|
-
pull-requests: write
|
|
1057
|
-
runs-on: ubuntu-latest
|
|
1058
|
-
timeout-minutes: 5
|
|
1059
|
-
concurrency:
|
|
1060
|
-
group: dependencies-\${{ github.event.pull_request.number }}
|
|
1061
|
-
cancel-in-progress: true
|
|
1062
|
-
if: github.event.pull_request.user.login == 'dependabot[bot]'
|
|
1063
|
-
steps:
|
|
1064
|
-
- uses: dependabot/fetch-metadata@25dd0e34f4fe68f24cc83900b1fe3fe149efef98 # v3.1.0
|
|
1065
|
-
name: Fetch Dependabot metadata
|
|
1066
|
-
id: metadata
|
|
1067
|
-
|
|
1068
|
-
- run: gh pr merge --auto --squash "$PR_URL"
|
|
1069
|
-
# --squash is intentional: repo protection sets allow_merge_commit: false,
|
|
1070
|
-
# so --merge would fail on any repo using the standard preset.
|
|
1071
|
-
name: Enable auto-merge for Dependabot PRs
|
|
1072
|
-
if: steps.metadata.outputs.update-type == 'version-update:semver-patch'
|
|
1073
|
-
env:
|
|
1074
|
-
PR_URL: \${{ github.event.pull_request.html_url }}
|
|
1075
|
-
GH_TOKEN: \${{ secrets.merge-token || github.token }}
|
|
1076
|
-
`,
|
|
1077
|
-
greetings: `\
|
|
1078
|
-
name: Greetings
|
|
1079
|
-
|
|
1080
|
-
on: # yamllint disable-line rule:truthy
|
|
1081
|
-
workflow_call:
|
|
1082
|
-
|
|
1083
|
-
jobs:
|
|
1084
|
-
greeting:
|
|
1085
|
-
name: Greet first-time contributors
|
|
1086
|
-
permissions:
|
|
1087
|
-
issues: write
|
|
1088
|
-
pull-requests: write
|
|
1089
|
-
runs-on: ubuntu-latest
|
|
1090
|
-
timeout-minutes: 5
|
|
1091
|
-
# Group by the issue/PR number so duplicate events don't race each other.
|
|
1092
|
-
concurrency:
|
|
1093
|
-
group: greetings-\${{ github.event.issue.number || github.event.pull_request.number }}
|
|
1094
|
-
cancel-in-progress: false
|
|
1095
|
-
steps:
|
|
1096
|
-
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
1097
|
-
name: Greet on first contribution
|
|
1098
|
-
with:
|
|
1099
|
-
script: |
|
|
1100
|
-
// Only greet on the initial open — ignore synchronize, reopened, etc.
|
|
1101
|
-
if (context.payload.action !== 'opened') return;
|
|
1102
|
-
|
|
1103
|
-
const actor = context.actor;
|
|
1104
|
-
const { owner, repo } = context.repo;
|
|
1105
|
-
|
|
1106
|
-
// Payload inspection is more reliable than context.eventName for detecting
|
|
1107
|
-
// whether this is an issue vs. PR event — works regardless of how GitHub
|
|
1108
|
-
// propagates event names through workflow_call chains.
|
|
1109
|
-
const isIssue = !!context.payload.issue && !context.payload.pull_request;
|
|
1110
|
-
// listForRepo returns both issues and PRs (GitHub treats PRs as issues),
|
|
1111
|
-
// sorted newest-first. Filter by type to track first-issue and first-PR
|
|
1112
|
-
// independently, and avoid search-index eventual-consistency lag.
|
|
1113
|
-
const { data: recent } = await github.rest.issues.listForRepo({
|
|
1114
|
-
owner, repo,
|
|
1115
|
-
creator: actor,
|
|
1116
|
-
state: 'all',
|
|
1117
|
-
per_page: 100
|
|
1118
|
-
});
|
|
1119
|
-
|
|
1120
|
-
const sameType = recent.filter(item =>
|
|
1121
|
-
isIssue ? !item.pull_request : !!item.pull_request
|
|
1122
|
-
);
|
|
1123
|
-
|
|
1124
|
-
if (sameType.length !== 1) return;
|
|
1125
|
-
const body = isIssue
|
|
1126
|
-
? \`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.\`
|
|
1127
|
-
: \`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.\`;
|
|
1128
|
-
|
|
1129
|
-
await github.rest.issues.createComment({
|
|
1130
|
-
owner,
|
|
1131
|
-
repo,
|
|
1132
|
-
issue_number: context.issue.number,
|
|
1133
|
-
body
|
|
1134
|
-
});
|
|
1135
|
-
`,
|
|
1136
|
-
lint: `\
|
|
1137
|
-
name: Lint
|
|
1138
|
-
|
|
1139
|
-
on: # yamllint disable-line rule:truthy
|
|
1140
|
-
workflow_call:
|
|
1141
|
-
inputs:
|
|
1142
|
-
prettier-config:
|
|
1143
|
-
type: string
|
|
1144
|
-
required: false
|
|
1145
|
-
default: prettier.config.js
|
|
1146
|
-
yaml-config:
|
|
1147
|
-
type: string
|
|
1148
|
-
required: false
|
|
1149
|
-
default: yamllint.config.yml
|
|
1150
|
-
enable-auto-commit:
|
|
1151
|
-
description: Auto-commit super-linter fixes via GPG-signed commit
|
|
1152
|
-
type: boolean
|
|
1153
|
-
required: false
|
|
1154
|
-
default: false
|
|
1155
|
-
secrets:
|
|
1156
|
-
SUPER_LINTER_GPG_PRIVATE_KEY:
|
|
1157
|
-
required: false
|
|
1158
|
-
SUPER_LINTER_GPG_PASSPHRASE:
|
|
1159
|
-
required: false
|
|
1160
|
-
|
|
1161
|
-
jobs:
|
|
1162
|
-
super-lint:
|
|
1163
|
-
name: Lint entire codebase
|
|
1164
|
-
permissions:
|
|
1165
|
-
contents: write
|
|
1166
|
-
statuses: write
|
|
1167
|
-
runs-on: ubuntu-latest
|
|
1168
|
-
timeout-minutes: 30
|
|
1169
|
-
env:
|
|
1170
|
-
GPG_KEY_SET: \${{ secrets.SUPER_LINTER_GPG_PRIVATE_KEY != '' }}
|
|
1171
|
-
steps:
|
|
1172
|
-
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
1173
|
-
name: Checkout repository
|
|
1174
|
-
with:
|
|
1175
|
-
fetch-depth: 0
|
|
1176
|
-
token: \${{ github.token }}
|
|
1177
|
-
|
|
1178
|
-
- uses: theholocron/.github/.github/actions/setup@main
|
|
1179
|
-
name: Setup
|
|
1180
|
-
if: \${{ hashFiles('pnpm-lock.yaml') != '' }}
|
|
1181
|
-
|
|
1182
|
-
- uses: super-linter/super-linter/slim@4ce20838b8ab83717e78138c5b3a1407148e0918 # v8.7.0
|
|
1183
|
-
name: Run Super Linter
|
|
1184
|
-
env:
|
|
1185
|
-
GITHUB_TOKEN: \${{ github.token }}
|
|
1186
|
-
DEFAULT_BRANCH: \${{ github.event.pull_request.base.ref || github.event.repository.default_branch }}
|
|
1187
|
-
ANNOTATE_ONLY: true
|
|
1188
|
-
DISABLE_COMMENTS: false
|
|
1189
|
-
IGNORE_GITIGNORED_FILES: true
|
|
1190
|
-
LINTER_RULES_PATH: /
|
|
1191
|
-
EDITORCONFIG_FILE_NAME: ".editorconfig-checker.json"
|
|
1192
|
-
FIX_ENV: true
|
|
1193
|
-
FIX_GRAPHQL_PRETTIER: true
|
|
1194
|
-
FIX_HTML_PRETTIER: true
|
|
1195
|
-
FIX_JAVASCRIPT_PRETTIER: true
|
|
1196
|
-
FIX_JSX_PRETTIER: true
|
|
1197
|
-
FIX_MARKDOWN_PRETTIER: true
|
|
1198
|
-
FIX_TSX: true
|
|
1199
|
-
FIX_TYPESCRIPT_PRETTIER: true
|
|
1200
|
-
PRETTIER_CONFIG: \${{ inputs.prettier-config }}
|
|
1201
|
-
VALIDATE_DOCKERFILE: true
|
|
1202
|
-
VALIDATE_EDITORCONFIG: true
|
|
1203
|
-
VALIDATE_ENV: true
|
|
1204
|
-
VALIDATE_GIT_COMMITLINT: true
|
|
1205
|
-
VALIDATE_GIT_MERGE_CONFLICT_MARKERS: true
|
|
1206
|
-
VALIDATE_GITHUB_ACTIONS: true
|
|
1207
|
-
VALIDATE_GITLEAKS: true
|
|
1208
|
-
VALIDATE_GRAPHQL_PRETTIER: true
|
|
1209
|
-
VALIDATE_HTML_PRETTIER: true
|
|
1210
|
-
VALIDATE_JAVASCRIPT_PRETTIER: true
|
|
1211
|
-
VALIDATE_JSX_PRETTIER: true
|
|
1212
|
-
VALIDATE_MARKDOWN_PRETTIER: true
|
|
1213
|
-
VALIDATE_TSX: true
|
|
1214
|
-
VALIDATE_TYPESCRIPT_PRETTIER: true
|
|
1215
|
-
VALIDATE_YAML: true
|
|
1216
|
-
YAML_CONFIG_FILE: \${{ inputs.yaml-config }}
|
|
1217
|
-
|
|
1218
|
-
- uses: crazy-max/ghaction-import-gpg@2dc316deee8e90f13e1a351ab510b4d5bc0c82cd # v7.0.0
|
|
1219
|
-
name: Import GPG Key
|
|
1220
|
-
# Conditions mirror auto-commit exactly — no point importing GPG if the
|
|
1221
|
-
# commit step will be skipped (fork PR, default branch, or secret unset).
|
|
1222
|
-
if: >
|
|
1223
|
-
inputs.enable-auto-commit == true &&
|
|
1224
|
-
github.event.pull_request != null &&
|
|
1225
|
-
github.event.pull_request.head.repo.full_name == github.repository &&
|
|
1226
|
-
github.ref_name != github.event.repository.default_branch &&
|
|
1227
|
-
env.GPG_KEY_SET == 'true'
|
|
1228
|
-
with:
|
|
1229
|
-
git_user_signingkey: true
|
|
1230
|
-
git_commit_gpgsign: true
|
|
1231
|
-
GPG_PRIVATE_KEY: \${{ secrets.SUPER_LINTER_GPG_PRIVATE_KEY }}
|
|
1232
|
-
PASSPHRASE: \${{ secrets.SUPER_LINTER_GPG_PASSPHRASE }}
|
|
1233
|
-
|
|
1234
|
-
- uses: stefanzweifel/git-auto-commit-action@4a55954c782fc1ea30b9056cd3e7a2b40ca8887d # v7.2.0
|
|
1235
|
-
name: Commit and push linting fixes
|
|
1236
|
-
if: >
|
|
1237
|
-
inputs.enable-auto-commit == true &&
|
|
1238
|
-
github.event.pull_request != null &&
|
|
1239
|
-
github.event.pull_request.head.repo.full_name == github.repository &&
|
|
1240
|
-
github.ref_name != github.event.repository.default_branch &&
|
|
1241
|
-
env.GPG_KEY_SET == 'true'
|
|
1242
|
-
with:
|
|
1243
|
-
branch: \${{ github.event.pull_request.head.ref || github.head_ref || github.ref }}
|
|
1244
|
-
commit_message: "chore: fix linting issues\\n\\nSigned-off-by: super-linter <super-linter@super-linter.dev>"
|
|
1245
|
-
commit_options: "--no-verify"
|
|
1246
|
-
commit_user_name: super-linter
|
|
1247
|
-
commit_user_email: super-linter@super-linter.dev
|
|
1248
|
-
`,
|
|
1249
|
-
release: `\
|
|
1250
|
-
name: Release
|
|
1251
|
-
|
|
1252
|
-
# Semantic-release with OIDC Trusted Publishing — no NPM_TOKEN required.
|
|
1253
|
-
# The calling repo must have a .releaserc.json that configures branches,
|
|
1254
|
-
# plugins, and any publish options. npm@11+ is installed to support OIDC.
|
|
1255
|
-
|
|
1256
|
-
on: # yamllint disable-line rule:truthy
|
|
1257
|
-
workflow_call:
|
|
1258
|
-
inputs:
|
|
1259
|
-
run-build:
|
|
1260
|
-
description: Run \`pnpm build\` before releasing
|
|
1261
|
-
type: boolean
|
|
1262
|
-
required: false
|
|
1263
|
-
default: true
|
|
1264
|
-
secrets:
|
|
1265
|
-
SYNC_TOKEN:
|
|
1266
|
-
description: >
|
|
1267
|
-
Optional PAT with Contents write access. Required when the default
|
|
1268
|
-
branch is protected by a ruleset — github.token cannot push through
|
|
1269
|
-
rulesets, but a PAT with admin bypass can. Falls back to github.token.
|
|
1270
|
-
required: false
|
|
1271
|
-
|
|
1272
|
-
jobs:
|
|
1273
|
-
release:
|
|
1274
|
-
name: Semantic release
|
|
1275
|
-
permissions:
|
|
1276
|
-
contents: write
|
|
1277
|
-
id-token: write
|
|
1278
|
-
issues: write
|
|
1279
|
-
pull-requests: write
|
|
1280
|
-
runs-on: ubuntu-latest
|
|
1281
|
-
timeout-minutes: 30
|
|
1282
|
-
# Do not cancel in-progress releases — a partial release is worse than a slow one.
|
|
1283
|
-
concurrency:
|
|
1284
|
-
group: release-\${{ github.ref }}
|
|
1285
|
-
cancel-in-progress: false
|
|
1286
|
-
steps:
|
|
1287
|
-
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
1288
|
-
name: Checkout repository
|
|
1289
|
-
with:
|
|
1290
|
-
fetch-depth: 0
|
|
1291
|
-
# Use SYNC_TOKEN when available — git push (tags, release commits)
|
|
1292
|
-
# uses the checkout credential, not GITHUB_TOKEN env var. The
|
|
1293
|
-
# built-in github.token cannot push through branch protection rulesets.
|
|
1294
|
-
token: \${{ secrets.SYNC_TOKEN || github.token }}
|
|
1295
|
-
|
|
1296
|
-
- uses: theholocron/.github/.github/actions/setup@main
|
|
1297
|
-
name: Setup
|
|
1298
|
-
|
|
1299
|
-
- name: Configure git identity
|
|
1300
|
-
run: |
|
|
1301
|
-
GIT_NAME=$(gh api user --jq .name 2>/dev/null || echo "github-actions[bot]")
|
|
1302
|
-
GIT_EMAIL=$(gh api user --jq '"\\(.id)+\\(.login)@users.noreply.github.com"' 2>/dev/null || echo "41898282+github-actions[bot]@users.noreply.github.com")
|
|
1303
|
-
git config --global user.name "$GIT_NAME"
|
|
1304
|
-
git config --global user.email "$GIT_EMAIL"
|
|
1305
|
-
git config --global format.signoff true
|
|
1306
|
-
env:
|
|
1307
|
-
GH_TOKEN: \${{ secrets.SYNC_TOKEN || github.token }}
|
|
1308
|
-
|
|
1309
|
-
- run: npm install -g npm@11 sigstore
|
|
1310
|
-
name: Upgrade npm for OIDC support
|
|
1311
|
-
# sigstore is required by libnpmpublish/provenance.js at module parse
|
|
1312
|
-
# time — before any config takes effect. Some npm 11.x builds stopped
|
|
1313
|
-
# bundling it; installing it globally into the same prefix ensures it
|
|
1314
|
-
# resolves regardless of npm version. (Discovered 2026-07-09.)
|
|
1315
|
-
|
|
1316
|
-
- run: pnpm build
|
|
1317
|
-
name: Build
|
|
1318
|
-
if: \${{ inputs.run-build == true }}
|
|
1319
|
-
|
|
1320
|
-
- run: npx semantic-release
|
|
1321
|
-
name: Release
|
|
1322
|
-
env:
|
|
1323
|
-
# Prefer SYNC_TOKEN (a PAT with Contents write) when available —
|
|
1324
|
-
# the built-in github.token cannot push to protected default branches
|
|
1325
|
-
# because rulesets block non-PAT pushes. Falls back to github.token
|
|
1326
|
-
# for repos without branch protection.
|
|
1327
|
-
GITHUB_TOKEN: \${{ secrets.SYNC_TOKEN || github.token }}
|
|
1328
|
-
NPM_CONFIG_PROVENANCE: true
|
|
1329
|
-
`,
|
|
1330
|
-
review: `\
|
|
1331
|
-
name: Review
|
|
1332
|
-
|
|
1333
|
-
# ReviewDog is the annotation layer — posts inline PR diff annotations.
|
|
1334
|
-
# Runs on pull_request only: inline annotations require PR context,
|
|
1335
|
-
# and branch protection ensures all changes go through PRs anyway.
|
|
1336
|
-
# super-linter (lint.yml) is the CI gate covering push + PR events.
|
|
1337
|
-
# Gitleaks and YAML are intentionally duplicated: super-linter gates
|
|
1338
|
-
# merges; ReviewDog surfaces exact line annotations in the PR diff.
|
|
1339
|
-
|
|
1340
|
-
on: # yamllint disable-line rule:truthy
|
|
1341
|
-
workflow_call:
|
|
1342
|
-
|
|
1343
|
-
concurrency:
|
|
1344
|
-
group: review-\${{ github.workflow }}-\${{ github.ref }}
|
|
1345
|
-
cancel-in-progress: true
|
|
1346
|
-
|
|
1347
|
-
jobs:
|
|
1348
|
-
reviewdog:
|
|
1349
|
-
name: Review PRs
|
|
1350
|
-
runs-on: ubuntu-latest
|
|
1351
|
-
timeout-minutes: 20
|
|
1352
|
-
permissions:
|
|
1353
|
-
contents: read
|
|
1354
|
-
checks: write
|
|
1355
|
-
pull-requests: write
|
|
1356
|
-
|
|
1357
|
-
steps:
|
|
1358
|
-
- name: Checkout repository
|
|
1359
|
-
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
1360
|
-
with:
|
|
1361
|
-
fetch-depth: 0
|
|
1362
|
-
|
|
1363
|
-
- name: Setup
|
|
1364
|
-
if: \${{ hashFiles('pnpm-lock.yaml') != '' }}
|
|
1365
|
-
uses: theholocron/.github/.github/actions/setup@main
|
|
1366
|
-
|
|
1367
|
-
- name: Install ReviewDog
|
|
1368
|
-
uses: reviewdog/action-setup@d8a7baabd7f3e8544ee4dbde3ee41d0011c3a93f # v1
|
|
1369
|
-
with:
|
|
1370
|
-
reviewdog_version: latest
|
|
1371
|
-
|
|
1372
|
-
# Detect which tools are relevant for this repo, excluding node_modules.
|
|
1373
|
-
# hashFiles('**/*') recurses into node_modules/.pnpm and produces false
|
|
1374
|
-
# positives for repos that don't own those file types.
|
|
1375
|
-
# -print -quit stops find after the first match without a pipe, avoiding
|
|
1376
|
-
# the SIGPIPE/pipefail exit-141 that find|head-1 triggers under
|
|
1377
|
-
# GitHub Actions' default bash --noprofile --norc -e -o pipefail mode.
|
|
1378
|
-
- name: Detect project features
|
|
1379
|
-
id: detect
|
|
1380
|
-
shell: bash
|
|
1381
|
-
run: |
|
|
1382
|
-
has() { find . -not -path '*/node_modules/*' -name "$1" -print -quit 2>/dev/null | grep -q .; }
|
|
1383
|
-
has_ext() { find . -not -path '*/node_modules/*' -name "$1" -print -quit 2>/dev/null | grep -q .; }
|
|
1384
|
-
{ { has 'eslint.config.js' || has 'eslint.config.mjs' || has 'eslint.config.cjs' || \\
|
|
1385
|
-
has 'eslint.config.ts' || has '.eslintrc' || has '.eslintrc.js' || \\
|
|
1386
|
-
has '.eslintrc.cjs' || has '.eslintrc.json' || has '.eslintrc.yaml' || \\
|
|
1387
|
-
has '.eslintrc.yml'; } && grep -qF '"eslint":' package.json 2>/dev/null; } && echo "eslint=true" >> "$GITHUB_OUTPUT" || echo "eslint=false" >> "$GITHUB_OUTPUT"
|
|
1388
|
-
{ has 'tsconfig.json' && grep -qF '"typescript":' package.json 2>/dev/null; } && echo "tsconfig=true" >> "$GITHUB_OUTPUT" || echo "tsconfig=false" >> "$GITHUB_OUTPUT"
|
|
1389
|
-
has_ext '*.sh' && echo "shell=true" >> "$GITHUB_OUTPUT" || echo "shell=false" >> "$GITHUB_OUTPUT"
|
|
1390
|
-
has 'Dockerfile' || has_ext '*.Dockerfile' || has 'Containerfile' && \\
|
|
1391
|
-
echo "docker=true" >> "$GITHUB_OUTPUT" || echo "docker=false" >> "$GITHUB_OUTPUT"
|
|
1392
|
-
has_ext '.env*' && echo "dotenv=true" >> "$GITHUB_OUTPUT" || echo "dotenv=false" >> "$GITHUB_OUTPUT"
|
|
1393
|
-
has_ext '*.md' && echo "markdown=true" >> "$GITHUB_OUTPUT" || echo "markdown=false" >> "$GITHUB_OUTPUT"
|
|
1394
|
-
|
|
1395
|
-
#
|
|
1396
|
-
# Always applicable
|
|
1397
|
-
#
|
|
1398
|
-
|
|
1399
|
-
- name: Gitleaks (secrets)
|
|
1400
|
-
uses: reviewdog/action-gitleaks@2b7b5685e3e3eecddab5d30cfa04f18123031421 # v1
|
|
1401
|
-
with:
|
|
1402
|
-
reporter: github-pr-check
|
|
1403
|
-
gitleaks_flags: --log-opts=\${{ github.event.pull_request.base.sha }}..\${{ github.event.pull_request.head.sha }}
|
|
1404
|
-
|
|
1405
|
-
- name: YamlLint
|
|
1406
|
-
if: \${{ hashFiles('yamllint.config.yml') != '' }}
|
|
1407
|
-
uses: reviewdog/action-yamllint@b5f7217d8c815ae374d1d55840d5e569d82f01f0 # v1
|
|
1408
|
-
with:
|
|
1409
|
-
reporter: github-pr-check
|
|
1410
|
-
yamllint_flags: -c \${{ github.workspace }}/yamllint.config.yml \${{ github.workspace }}
|
|
1411
|
-
|
|
1412
|
-
- name: ActionLint (GitHub Actions)
|
|
1413
|
-
if: \${{ hashFiles('.github/workflows/*.yml', '.github/workflows/*.yaml') != '' }}
|
|
1414
|
-
uses: reviewdog/action-actionlint@6fb7acc99f4a1008869fa8a0f09cfca740837d9d # v1
|
|
1415
|
-
with:
|
|
1416
|
-
reporter: github-pr-check
|
|
1417
|
-
|
|
1418
|
-
#
|
|
1419
|
-
# TypeScript / JavaScript
|
|
1420
|
-
#
|
|
1421
|
-
|
|
1422
|
-
- name: ESLint
|
|
1423
|
-
if: steps.detect.outputs.eslint == 'true'
|
|
1424
|
-
uses: reviewdog/action-eslint@556a3fdaf8b4201d4d74d406013386aa4f7dab96 # v1.34.0
|
|
1425
|
-
with:
|
|
1426
|
-
reporter: github-pr-check
|
|
1427
|
-
eslint_flags: .
|
|
1428
|
-
|
|
1429
|
-
- name: TypeScript
|
|
1430
|
-
if: steps.detect.outputs.tsconfig == 'true'
|
|
1431
|
-
uses: EPMatt/reviewdog-action-tsc@63d923a3c5b4497671940b8874f58a404e2351b5 # v1
|
|
1432
|
-
with:
|
|
1433
|
-
reporter: github-pr-check
|
|
1434
|
-
|
|
1435
|
-
#
|
|
1436
|
-
# Shell
|
|
1437
|
-
#
|
|
1438
|
-
|
|
1439
|
-
- name: ShellCheck
|
|
1440
|
-
if: steps.detect.outputs.shell == 'true'
|
|
1441
|
-
uses: reviewdog/action-shellcheck@4c07458293ac342d477251099501a718ae5ef86e # v1
|
|
1442
|
-
with:
|
|
1443
|
-
reporter: github-pr-check
|
|
1444
|
-
fail_level: none
|
|
1445
|
-
|
|
1446
|
-
#
|
|
1447
|
-
# Docker
|
|
1448
|
-
#
|
|
1449
|
-
|
|
1450
|
-
- name: Hadolint
|
|
1451
|
-
if: steps.detect.outputs.docker == 'true'
|
|
1452
|
-
uses: reviewdog/action-hadolint@1b2cfa6ba72072ad35158d7ff3aa49bbdc03506d # v1
|
|
1453
|
-
with:
|
|
1454
|
-
reporter: github-pr-check
|
|
1455
|
-
fail_level: none
|
|
1456
|
-
|
|
1457
|
-
#
|
|
1458
|
-
# Environment files
|
|
1459
|
-
#
|
|
1460
|
-
|
|
1461
|
-
- name: dotenv-linter
|
|
1462
|
-
if: steps.detect.outputs.dotenv == 'true'
|
|
1463
|
-
uses: dotenv-linter/action-dotenv-linter@afde61cfda2ecffe7bea35837b6f20b956c88689 # v3.0.0
|
|
1464
|
-
with:
|
|
1465
|
-
reporter: github-code-suggestions
|
|
1466
|
-
|
|
1467
|
-
#
|
|
1468
|
-
# Documentation
|
|
1469
|
-
#
|
|
1470
|
-
|
|
1471
|
-
- name: Alex (inclusive language)
|
|
1472
|
-
if: steps.detect.outputs.markdown == 'true'
|
|
1473
|
-
uses: reviewdog/action-alex@347481655add010a2ae302df34b57c9bcfa0d6e4 # v1
|
|
1474
|
-
with:
|
|
1475
|
-
reporter: github-pr-check
|
|
1476
|
-
`,
|
|
1477
|
-
stale: `\
|
|
1478
|
-
name: Stale
|
|
1479
|
-
|
|
1480
|
-
on: # yamllint disable-line rule:truthy
|
|
1481
|
-
workflow_call:
|
|
1482
|
-
inputs:
|
|
1483
|
-
days-before-stale:
|
|
1484
|
-
description: Days of inactivity before an issue is marked stale
|
|
1485
|
-
type: number
|
|
1486
|
-
required: false
|
|
1487
|
-
default: 30
|
|
1488
|
-
days-before-close:
|
|
1489
|
-
description: Days of inactivity after stale label before closing
|
|
1490
|
-
type: number
|
|
1491
|
-
required: false
|
|
1492
|
-
default: 5
|
|
1493
|
-
|
|
1494
|
-
jobs:
|
|
1495
|
-
stale:
|
|
1496
|
-
name: Mark stale issues and pull requests
|
|
1497
|
-
permissions:
|
|
1498
|
-
contents: write
|
|
1499
|
-
issues: write
|
|
1500
|
-
pull-requests: write
|
|
1501
|
-
runs-on: ubuntu-latest
|
|
1502
|
-
timeout-minutes: 10
|
|
1503
|
-
steps:
|
|
1504
|
-
- uses: actions/stale@1e223db275d687790206a7acac4d1a11bd6fe629 # v10.4.0
|
|
1505
|
-
name: Run Stale
|
|
1506
|
-
with:
|
|
1507
|
-
close-issue-message: >
|
|
1508
|
-
This issue was closed because it has been stalled for
|
|
1509
|
-
\${{ inputs.days-before-close }} days with no activity.
|
|
1510
|
-
days-before-close: \${{ inputs.days-before-close }}
|
|
1511
|
-
days-before-stale: \${{ inputs.days-before-stale }}
|
|
1512
|
-
exempt-all-pr-milestones: true
|
|
1513
|
-
stale-issue-label: wontfix
|
|
1514
|
-
stale-issue-message: >
|
|
1515
|
-
This issue is stale because it has been open \${{ inputs.days-before-stale }}
|
|
1516
|
-
days with no activity. Remove the stale label or comment, or this will be
|
|
1517
|
-
closed in \${{ inputs.days-before-close }} days.
|
|
1518
|
-
stale-pr-label: wontfix
|
|
1519
|
-
stale-pr-message: >
|
|
1520
|
-
This PR is stale because it has been open \${{ inputs.days-before-stale }}
|
|
1521
|
-
days with no activity. Remove the stale label or comment, or this will be
|
|
1522
|
-
closed in \${{ inputs.days-before-close }} days.
|
|
1523
|
-
`,
|
|
1524
|
-
test: `\
|
|
1525
|
-
name: Test
|
|
1526
|
-
|
|
1527
|
-
on: # yamllint disable-line rule:truthy
|
|
1528
|
-
workflow_call:
|
|
1529
|
-
secrets:
|
|
1530
|
-
CODECOV_TOKEN:
|
|
1531
|
-
required: false
|
|
1532
|
-
|
|
1533
|
-
jobs:
|
|
1534
|
-
unit:
|
|
1535
|
-
name: Run tests and collect coverage
|
|
1536
|
-
permissions:
|
|
1537
|
-
contents: read
|
|
1538
|
-
runs-on: ubuntu-latest
|
|
1539
|
-
timeout-minutes: 15
|
|
1540
|
-
steps:
|
|
1541
|
-
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
1542
|
-
name: Checkout repository
|
|
1543
|
-
with:
|
|
1544
|
-
fetch-depth: 0
|
|
1545
|
-
|
|
1546
|
-
- uses: theholocron/.github/.github/actions/setup@main
|
|
1547
|
-
name: Setup
|
|
1548
|
-
|
|
1549
|
-
- run: pnpm test -- --coverage
|
|
1550
|
-
name: Run tests with coverage
|
|
1551
|
-
|
|
1552
|
-
- uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
1553
|
-
name: Upload coverage to Codecov
|
|
1554
|
-
with:
|
|
1555
|
-
token: \${{ secrets.CODECOV_TOKEN }}
|
|
1556
|
-
|
|
1557
|
-
- uses: codecov/test-results-action@0fa95f0e1eeaafde2c782583b36b28ad0d8c77d3 # v1
|
|
1558
|
-
name: Upload test results to Codecov
|
|
1559
|
-
if: \${{ !cancelled() }}
|
|
1560
|
-
with:
|
|
1561
|
-
token: \${{ secrets.CODECOV_TOKEN }}
|
|
1562
|
-
files: '**/test-report.junit.xml'
|
|
1563
|
-
`,
|
|
1564
|
-
"sync-github": `\
|
|
1565
|
-
name: Sync GitHub Templates
|
|
1566
|
-
|
|
1567
|
-
# Builds the holocron CLI from source and pushes updated workflow templates
|
|
1568
|
-
# and composite actions to downstream .github repos. Runs whenever the
|
|
1569
|
-
# template source files change on main or alpha.
|
|
1570
|
-
#
|
|
1571
|
-
# Secrets required:
|
|
1572
|
-
# SYNC_TOKEN — fine-grained PAT (resource owner: org) with:
|
|
1573
|
-
# Contents: Read and write (git trees, blobs, refs)
|
|
1574
|
-
# Pull requests: Read and write (open sync PR)
|
|
1575
|
-
# Workflows: Read and write (write .github/workflows/*.yml)
|
|
1576
|
-
|
|
1577
|
-
on: # yamllint disable-line rule:truthy
|
|
1578
|
-
workflow_call:
|
|
1579
|
-
inputs:
|
|
1580
|
-
primary-repo:
|
|
1581
|
-
description: >
|
|
1582
|
-
Primary .github repo — receives composite actions, reusable workflows,
|
|
1583
|
-
and thin-caller templates. Requires a PR (branch protection assumed).
|
|
1584
|
-
type: string
|
|
1585
|
-
required: false
|
|
1586
|
-
default: theholocron/.github
|
|
1587
|
-
secondary-repos:
|
|
1588
|
-
description: >
|
|
1589
|
-
Space-separated list of secondary repos (reusable workflows + thin
|
|
1590
|
-
callers only, no composite actions). Changes are delivered via pull
|
|
1591
|
-
request, same as the primary repo.
|
|
1592
|
-
type: string
|
|
1593
|
-
required: false
|
|
1594
|
-
default: ""
|
|
1595
|
-
sync-branch:
|
|
1596
|
-
description: Branch name used for the primary and secondary repo PRs
|
|
1597
|
-
type: string
|
|
1598
|
-
required: false
|
|
1599
|
-
default: chore/sync-templates
|
|
1600
|
-
secrets:
|
|
1601
|
-
SYNC_TOKEN:
|
|
1602
|
-
required: true
|
|
1603
|
-
|
|
1604
|
-
jobs:
|
|
1605
|
-
sync:
|
|
1606
|
-
name: Sync templates
|
|
1607
|
-
runs-on: ubuntu-latest
|
|
1608
|
-
timeout-minutes: 15
|
|
1609
|
-
permissions:
|
|
1610
|
-
contents: read
|
|
1611
|
-
steps:
|
|
1612
|
-
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
1613
|
-
name: Checkout repository
|
|
1614
|
-
|
|
1615
|
-
- uses: theholocron/.github/.github/actions/setup@main
|
|
1616
|
-
name: Setup
|
|
1617
|
-
|
|
1618
|
-
- run: pnpm build
|
|
1619
|
-
name: Build CLI
|
|
1620
|
-
|
|
1621
|
-
- name: Validate generated workflows
|
|
1622
|
-
run: |
|
|
1623
|
-
node packages/cli/dist/cli.mjs sync-github \\
|
|
1624
|
-
--repo "$PRIMARY_REPO" \\
|
|
1625
|
-
--output-dir /tmp/sync-validate
|
|
1626
|
-
curl -fsSL https://github.com/rhysd/actionlint/releases/download/v1.7.7/actionlint_1.7.7_linux_amd64.tar.gz \\
|
|
1627
|
-
| tar -xz -C /tmp actionlint
|
|
1628
|
-
/tmp/actionlint /tmp/sync-validate/.github/workflows/*.yml
|
|
1629
|
-
env:
|
|
1630
|
-
PRIMARY_REPO: \${{ inputs.primary-repo }}
|
|
1631
|
-
|
|
1632
|
-
- name: Sync primary repo (PR)
|
|
1633
|
-
run: |
|
|
1634
|
-
GIT_NAME=$(gh api user --jq .name 2>/dev/null || echo "github-actions[bot]")
|
|
1635
|
-
GIT_EMAIL=$(gh api user --jq '"\\(.id)+\\(.login)@users.noreply.github.com"' 2>/dev/null || echo "41898282+github-actions[bot]@users.noreply.github.com")
|
|
1636
|
-
COMMIT_MSG="chore: sync from theholocron/holocron"$'\\n\\n'"Signed-off-by: $GIT_NAME <$GIT_EMAIL>"
|
|
1637
|
-
node packages/cli/dist/cli.mjs sync-github \\
|
|
1638
|
-
--repo "$PRIMARY_REPO" \\
|
|
1639
|
-
--branch "$SYNC_BRANCH" \\
|
|
1640
|
-
--pr \\
|
|
1641
|
-
--message "$COMMIT_MSG"
|
|
1642
|
-
env:
|
|
1643
|
-
GITHUB_TOKEN: \${{ secrets.SYNC_TOKEN }}
|
|
1644
|
-
GH_TOKEN: \${{ secrets.SYNC_TOKEN }}
|
|
1645
|
-
PRIMARY_REPO: \${{ inputs.primary-repo }}
|
|
1646
|
-
SYNC_BRANCH: \${{ inputs.sync-branch }}
|
|
1647
|
-
|
|
1648
|
-
- name: Sync secondary repos (PR)
|
|
1649
|
-
if: \${{ inputs.secondary-repos != '' }}
|
|
1650
|
-
run: |
|
|
1651
|
-
GIT_NAME=$(gh api user --jq .name 2>/dev/null || echo "github-actions[bot]")
|
|
1652
|
-
GIT_EMAIL=$(gh api user --jq '"\\(.id)+\\(.login)@users.noreply.github.com"' 2>/dev/null || echo "41898282+github-actions[bot]@users.noreply.github.com")
|
|
1653
|
-
COMMIT_MSG="chore: sync from theholocron/holocron"$'\\n\\n'"Signed-off-by: $GIT_NAME <$GIT_EMAIL>"
|
|
1654
|
-
for repo in $SECONDARY_REPOS; do
|
|
1655
|
-
node packages/cli/dist/cli.mjs sync-github \\
|
|
1656
|
-
--repo "$repo" \\
|
|
1657
|
-
--branch "$SYNC_BRANCH" \\
|
|
1658
|
-
--pr \\
|
|
1659
|
-
--message "$COMMIT_MSG"
|
|
1660
|
-
done
|
|
1661
|
-
env:
|
|
1662
|
-
GITHUB_TOKEN: \${{ secrets.SYNC_TOKEN }}
|
|
1663
|
-
GH_TOKEN: \${{ secrets.SYNC_TOKEN }}
|
|
1664
|
-
SECONDARY_REPOS: \${{ inputs.secondary-repos }}
|
|
1665
|
-
SYNC_BRANCH: \${{ inputs.sync-branch }}
|
|
1666
|
-
`,
|
|
1667
|
-
typecheck: `\
|
|
1668
|
-
name: Typecheck
|
|
1669
|
-
|
|
1670
|
-
on: # yamllint disable-line rule:truthy
|
|
1671
|
-
workflow_call:
|
|
1672
|
-
|
|
1673
|
-
jobs:
|
|
1674
|
-
typecheck:
|
|
1675
|
-
name: tsc --noEmit
|
|
1676
|
-
permissions:
|
|
1677
|
-
contents: read
|
|
1678
|
-
runs-on: ubuntu-latest
|
|
1679
|
-
timeout-minutes: 10
|
|
1680
|
-
steps:
|
|
1681
|
-
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
1682
|
-
name: Checkout repository
|
|
1683
|
-
|
|
1684
|
-
- uses: theholocron/.github/.github/actions/setup@main
|
|
1685
|
-
name: Setup
|
|
1686
|
-
|
|
1687
|
-
- run: pnpm typecheck
|
|
1688
|
-
name: Type check
|
|
1689
|
-
`
|
|
899
|
+
audit: audit_default$1,
|
|
900
|
+
bookkeeping: bookkeeping_default$1,
|
|
901
|
+
codeql: codeql_default$1,
|
|
902
|
+
dependencies: dependencies_default$1,
|
|
903
|
+
greetings: greetings_default$1,
|
|
904
|
+
lint: lint_default$1,
|
|
905
|
+
release: release_default$1,
|
|
906
|
+
review: review_default$1,
|
|
907
|
+
stale: stale_default$1,
|
|
908
|
+
"sync-github": sync_github_default$1,
|
|
909
|
+
test: test_default$1,
|
|
910
|
+
typecheck: typecheck_default$1
|
|
911
|
+
};
|
|
912
|
+
const WORKFLOW_TEMPLATE_PROPERTIES = {
|
|
913
|
+
bookkeeping: JSON.stringify({
|
|
914
|
+
name: "Bookkeeping",
|
|
915
|
+
description: "Label and track issues and pull requests.",
|
|
916
|
+
iconName: "octicon tag"
|
|
917
|
+
}, null, 2),
|
|
918
|
+
"sync-github": JSON.stringify({
|
|
919
|
+
name: "Sync GitHub Templates",
|
|
920
|
+
description: "Sync workflow templates and composite actions from the holocron CLI.",
|
|
921
|
+
iconName: "octicon sync"
|
|
922
|
+
}, null, 2)
|
|
1690
923
|
};
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
924
|
+
//#endregion
|
|
925
|
+
//#region src/commands/dependabot.yml
|
|
926
|
+
var dependabot_default = "# AUTO-GENERATED by holocron — run `holocron setup` to regenerate.\nversion: 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";
|
|
927
|
+
//#endregion
|
|
928
|
+
//#region src/commands/workflows/audit.yml
|
|
929
|
+
var audit_default = "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";
|
|
930
|
+
//#endregion
|
|
931
|
+
//#region src/commands/workflows/bookkeeping.yml
|
|
932
|
+
var bookkeeping_default = "name: Bookkeeping\n\non: # yamllint disable-line rule:truthy\n pull_request:\n types:\n - opened\n - edited\n issues:\n types:\n - opened\n - edited\n\npermissions:\n contents: read\n issues: write\n pull-requests: write\n\njobs:\n bookkeeping:\n uses: theholocron/.github/.github/workflows/bookkeeping.yml@main\n secrets: inherit\n";
|
|
933
|
+
//#endregion
|
|
934
|
+
//#region src/commands/workflows/codeql.yml
|
|
935
|
+
var codeql_default = "name: CodeQL\n\non: # yamllint disable-line rule:truthy\n push:\n branches:\n - main\n pull_request:\n branches:\n - main\n schedule:\n - cron: \"0 0 * * 1\"\n\npermissions:\n actions: read\n contents: read\n security-events: write\n\njobs:\n codeql:\n uses: theholocron/.github/.github/workflows/codeql.yml@main\n secrets: inherit\n";
|
|
936
|
+
//#endregion
|
|
937
|
+
//#region src/commands/workflows/dependencies.yml
|
|
938
|
+
var dependencies_default = "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";
|
|
939
|
+
//#endregion
|
|
940
|
+
//#region src/commands/workflows/greetings.yml
|
|
941
|
+
var greetings_default = "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";
|
|
942
|
+
//#endregion
|
|
943
|
+
//#region src/commands/workflows/lint.yml
|
|
944
|
+
var lint_default = "name: Lint\n\non: # yamllint disable-line rule:truthy\n push:\n branches: [main, alpha]\n pull_request:\n\nconcurrency:\n group: lint-${{ github.ref }}\n cancel-in-progress: true\n\npermissions:\n contents: write\n statuses: write\n\njobs:\n lint:\n name: Lint\n uses: theholocron/.github/.github/workflows/lint.yml@main\n secrets: inherit\n with:\n enable-auto-commit: true\n";
|
|
945
|
+
//#endregion
|
|
946
|
+
//#region src/commands/workflows/release.yml
|
|
947
|
+
var release_default = "name: Release\n\non: # yamllint disable-line rule:truthy\n push:\n branches:\n - main\n - alpha\n workflow_dispatch:\n\npermissions:\n contents: write\n id-token: write\n issues: write\n pull-requests: write\n\nconcurrency:\n group: ${{ github.workflow }}-${{ github.ref }}\n cancel-in-progress: false\n\njobs:\n release:\n uses: theholocron/.github/.github/workflows/release.yml@main\n secrets: inherit\n";
|
|
948
|
+
//#endregion
|
|
949
|
+
//#region src/commands/workflows/review.yml
|
|
950
|
+
var review_default = "name: Review\n\non: # yamllint disable-line rule:truthy\n pull_request:\n\nconcurrency:\n group: review-${{ github.ref }}\n cancel-in-progress: true\n\npermissions:\n contents: read\n checks: write\n pull-requests: write\n\njobs:\n review:\n name: Review\n uses: theholocron/.github/.github/workflows/review.yml@main\n secrets: inherit\n";
|
|
951
|
+
//#endregion
|
|
952
|
+
//#region src/commands/workflows/stale.yml
|
|
953
|
+
var stale_default = "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";
|
|
954
|
+
//#endregion
|
|
955
|
+
//#region src/commands/workflows/sync-github.yml
|
|
956
|
+
var sync_github_default = "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 SYNC_TOKEN: ${{ secrets.SYNC_TOKEN }}\n";
|
|
957
|
+
//#endregion
|
|
958
|
+
//#region src/commands/workflows/test.yml
|
|
959
|
+
var test_default = "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\njobs:\n test:\n name: Test\n uses: theholocron/.github/.github/workflows/test.yml@main\n secrets: inherit\n";
|
|
960
|
+
//#endregion
|
|
961
|
+
//#region src/commands/workflows/typecheck.yml
|
|
962
|
+
var typecheck_default = "name: Typecheck\n\non: # yamllint disable-line rule:truthy\n push:\n branches: [main, alpha]\n pull_request:\n\nconcurrency:\n group: typecheck-${{ github.ref }}\n cancel-in-progress: true\n\npermissions:\n contents: read\n\njobs:\n typecheck:\n name: Typecheck\n uses: theholocron/.github/.github/workflows/typecheck.yml@main\n secrets: inherit\n";
|
|
1696
963
|
//#endregion
|
|
1697
964
|
//#region src/commands/setup-workflows.ts
|
|
1698
|
-
/**
|
|
1699
|
-
* Thin workflow wrapper templates for `holocron setup`.
|
|
1700
|
-
*
|
|
1701
|
-
* Each entry is a complete `.github/workflows/<name>.yml` that delegates
|
|
1702
|
-
* to the corresponding reusable `ci-<name>.yml` in `theholocron/.github`.
|
|
1703
|
-
* Files are overwritten on each setup run — they are generated artifacts.
|
|
1704
|
-
*/
|
|
1705
|
-
const WORKFLOW_REPO = "theholocron/.github";
|
|
1706
|
-
const WORKFLOW_REF = "main";
|
|
1707
|
-
function ref(name) {
|
|
1708
|
-
return `${WORKFLOW_REPO}/.github/workflows/${name}.yml@${WORKFLOW_REF}`;
|
|
1709
|
-
}
|
|
1710
965
|
/** Header prepended when holocron setup writes a thin caller to a repo. */
|
|
1711
966
|
function workflowHeader() {
|
|
1712
967
|
return [
|
|
@@ -1719,254 +974,18 @@ function workflowHeader() {
|
|
|
1719
974
|
].join("\n");
|
|
1720
975
|
}
|
|
1721
976
|
const WORKFLOW_TEMPLATES = {
|
|
1722
|
-
lint:
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
permissions:
|
|
1735
|
-
contents: write
|
|
1736
|
-
statuses: write
|
|
1737
|
-
|
|
1738
|
-
jobs:
|
|
1739
|
-
lint:
|
|
1740
|
-
name: Lint
|
|
1741
|
-
uses: ${ref("lint")}
|
|
1742
|
-
secrets: inherit
|
|
1743
|
-
with:
|
|
1744
|
-
enable-auto-commit: true
|
|
1745
|
-
`,
|
|
1746
|
-
test: `\
|
|
1747
|
-
name: Test
|
|
1748
|
-
|
|
1749
|
-
on: # yamllint disable-line rule:truthy
|
|
1750
|
-
push:
|
|
1751
|
-
branches: [main, alpha]
|
|
1752
|
-
pull_request:
|
|
1753
|
-
|
|
1754
|
-
concurrency:
|
|
1755
|
-
group: test-\${{ github.ref }}
|
|
1756
|
-
cancel-in-progress: true
|
|
1757
|
-
|
|
1758
|
-
permissions:
|
|
1759
|
-
contents: read
|
|
1760
|
-
|
|
1761
|
-
jobs:
|
|
1762
|
-
test:
|
|
1763
|
-
name: Test
|
|
1764
|
-
uses: ${ref("test")}
|
|
1765
|
-
secrets: inherit
|
|
1766
|
-
`,
|
|
1767
|
-
typecheck: `\
|
|
1768
|
-
name: Typecheck
|
|
1769
|
-
|
|
1770
|
-
on: # yamllint disable-line rule:truthy
|
|
1771
|
-
push:
|
|
1772
|
-
branches: [main, alpha]
|
|
1773
|
-
pull_request:
|
|
1774
|
-
|
|
1775
|
-
concurrency:
|
|
1776
|
-
group: typecheck-\${{ github.ref }}
|
|
1777
|
-
cancel-in-progress: true
|
|
1778
|
-
|
|
1779
|
-
permissions:
|
|
1780
|
-
contents: read
|
|
1781
|
-
|
|
1782
|
-
jobs:
|
|
1783
|
-
typecheck:
|
|
1784
|
-
name: Typecheck
|
|
1785
|
-
uses: ${ref("typecheck")}
|
|
1786
|
-
secrets: inherit
|
|
1787
|
-
`,
|
|
1788
|
-
codeql: `\
|
|
1789
|
-
name: CodeQL
|
|
1790
|
-
|
|
1791
|
-
on: # yamllint disable-line rule:truthy
|
|
1792
|
-
push:
|
|
1793
|
-
branches:
|
|
1794
|
-
- main
|
|
1795
|
-
pull_request:
|
|
1796
|
-
branches:
|
|
1797
|
-
- main
|
|
1798
|
-
schedule:
|
|
1799
|
-
- cron: "0 0 * * 1"
|
|
1800
|
-
|
|
1801
|
-
permissions:
|
|
1802
|
-
actions: read
|
|
1803
|
-
contents: read
|
|
1804
|
-
security-events: write
|
|
1805
|
-
|
|
1806
|
-
jobs:
|
|
1807
|
-
codeql:
|
|
1808
|
-
uses: ${ref("codeql")}
|
|
1809
|
-
secrets: inherit
|
|
1810
|
-
`,
|
|
1811
|
-
review: `\
|
|
1812
|
-
name: Review
|
|
1813
|
-
|
|
1814
|
-
on: # yamllint disable-line rule:truthy
|
|
1815
|
-
pull_request:
|
|
1816
|
-
|
|
1817
|
-
concurrency:
|
|
1818
|
-
group: review-\${{ github.ref }}
|
|
1819
|
-
cancel-in-progress: true
|
|
1820
|
-
|
|
1821
|
-
permissions:
|
|
1822
|
-
contents: read
|
|
1823
|
-
checks: write
|
|
1824
|
-
pull-requests: write
|
|
1825
|
-
|
|
1826
|
-
jobs:
|
|
1827
|
-
review:
|
|
1828
|
-
name: Review
|
|
1829
|
-
uses: ${ref("review")}
|
|
1830
|
-
secrets: inherit
|
|
1831
|
-
`,
|
|
1832
|
-
release: `\
|
|
1833
|
-
name: Release
|
|
1834
|
-
|
|
1835
|
-
on: # yamllint disable-line rule:truthy
|
|
1836
|
-
push:
|
|
1837
|
-
branches:
|
|
1838
|
-
- main
|
|
1839
|
-
- alpha
|
|
1840
|
-
workflow_dispatch:
|
|
1841
|
-
|
|
1842
|
-
permissions:
|
|
1843
|
-
contents: write
|
|
1844
|
-
id-token: write
|
|
1845
|
-
issues: write
|
|
1846
|
-
pull-requests: write
|
|
1847
|
-
|
|
1848
|
-
concurrency:
|
|
1849
|
-
group: \${{ github.workflow }}-\${{ github.ref }}
|
|
1850
|
-
cancel-in-progress: false
|
|
1851
|
-
|
|
1852
|
-
jobs:
|
|
1853
|
-
release:
|
|
1854
|
-
uses: ${ref("release")}
|
|
1855
|
-
secrets: inherit
|
|
1856
|
-
`,
|
|
1857
|
-
stale: `\
|
|
1858
|
-
name: Stale
|
|
1859
|
-
|
|
1860
|
-
on: # yamllint disable-line rule:truthy
|
|
1861
|
-
schedule:
|
|
1862
|
-
- cron: "30 1 * * *"
|
|
1863
|
-
|
|
1864
|
-
permissions:
|
|
1865
|
-
contents: write
|
|
1866
|
-
issues: write
|
|
1867
|
-
pull-requests: write
|
|
1868
|
-
|
|
1869
|
-
jobs:
|
|
1870
|
-
stale:
|
|
1871
|
-
uses: ${ref("stale")}
|
|
1872
|
-
secrets: inherit
|
|
1873
|
-
`,
|
|
1874
|
-
greetings: `\
|
|
1875
|
-
name: Greetings
|
|
1876
|
-
|
|
1877
|
-
on: # yamllint disable-line rule:truthy
|
|
1878
|
-
pull_request:
|
|
1879
|
-
issues:
|
|
1880
|
-
|
|
1881
|
-
permissions:
|
|
1882
|
-
issues: write
|
|
1883
|
-
pull-requests: write
|
|
1884
|
-
|
|
1885
|
-
jobs:
|
|
1886
|
-
greetings:
|
|
1887
|
-
uses: ${ref("greetings")}
|
|
1888
|
-
secrets: inherit
|
|
1889
|
-
`,
|
|
1890
|
-
dependencies: `\
|
|
1891
|
-
name: Dependencies
|
|
1892
|
-
|
|
1893
|
-
on: # yamllint disable-line rule:truthy
|
|
1894
|
-
pull_request:
|
|
1895
|
-
|
|
1896
|
-
permissions:
|
|
1897
|
-
contents: write
|
|
1898
|
-
pull-requests: write
|
|
1899
|
-
|
|
1900
|
-
jobs:
|
|
1901
|
-
dependencies:
|
|
1902
|
-
uses: ${ref("dependencies")}
|
|
1903
|
-
secrets: inherit
|
|
1904
|
-
`,
|
|
1905
|
-
bookkeeping: `\
|
|
1906
|
-
name: Bookkeeping
|
|
1907
|
-
|
|
1908
|
-
on: # yamllint disable-line rule:truthy
|
|
1909
|
-
pull_request:
|
|
1910
|
-
types:
|
|
1911
|
-
- opened
|
|
1912
|
-
- edited
|
|
1913
|
-
issues:
|
|
1914
|
-
types:
|
|
1915
|
-
- opened
|
|
1916
|
-
- edited
|
|
1917
|
-
|
|
1918
|
-
permissions:
|
|
1919
|
-
contents: read
|
|
1920
|
-
issues: write
|
|
1921
|
-
pull-requests: write
|
|
1922
|
-
|
|
1923
|
-
jobs:
|
|
1924
|
-
bookkeeping:
|
|
1925
|
-
uses: ${ref("bookkeeping")}
|
|
1926
|
-
secrets: inherit
|
|
1927
|
-
`,
|
|
1928
|
-
audit: `\
|
|
1929
|
-
name: Audit
|
|
1930
|
-
|
|
1931
|
-
on: # yamllint disable-line rule:truthy
|
|
1932
|
-
push:
|
|
1933
|
-
branches: [main, alpha]
|
|
1934
|
-
pull_request:
|
|
1935
|
-
|
|
1936
|
-
permissions:
|
|
1937
|
-
contents: read
|
|
1938
|
-
|
|
1939
|
-
jobs:
|
|
1940
|
-
audit:
|
|
1941
|
-
uses: ${ref("audit")}
|
|
1942
|
-
secrets: inherit
|
|
1943
|
-
`,
|
|
1944
|
-
"sync-github": `\
|
|
1945
|
-
name: Sync GitHub Templates
|
|
1946
|
-
|
|
1947
|
-
on: # yamllint disable-line rule:truthy
|
|
1948
|
-
push:
|
|
1949
|
-
branches: [main, alpha]
|
|
1950
|
-
paths:
|
|
1951
|
-
- packages/cli/src/templates/index.ts
|
|
1952
|
-
- packages/cli/src/commands/setup-workflows.ts
|
|
1953
|
-
|
|
1954
|
-
concurrency:
|
|
1955
|
-
group: sync-github-\${{ github.ref }}
|
|
1956
|
-
cancel-in-progress: true
|
|
1957
|
-
|
|
1958
|
-
permissions:
|
|
1959
|
-
contents: read
|
|
1960
|
-
|
|
1961
|
-
jobs:
|
|
1962
|
-
sync:
|
|
1963
|
-
name: Sync
|
|
1964
|
-
uses: ${ref("sync-github")}
|
|
1965
|
-
with:
|
|
1966
|
-
secondary-repos: theholocron/.github-private
|
|
1967
|
-
secrets:
|
|
1968
|
-
SYNC_TOKEN: \${{ secrets.SYNC_TOKEN }}
|
|
1969
|
-
`
|
|
977
|
+
lint: lint_default,
|
|
978
|
+
test: test_default,
|
|
979
|
+
typecheck: typecheck_default,
|
|
980
|
+
codeql: codeql_default,
|
|
981
|
+
review: review_default,
|
|
982
|
+
release: release_default,
|
|
983
|
+
stale: stale_default,
|
|
984
|
+
greetings: greetings_default,
|
|
985
|
+
dependencies: dependencies_default,
|
|
986
|
+
bookkeeping: bookkeeping_default,
|
|
987
|
+
audit: audit_default,
|
|
988
|
+
"sync-github": sync_github_default
|
|
1970
989
|
};
|
|
1971
990
|
const KNOWN_WORKFLOWS = new Set(Object.keys(WORKFLOW_TEMPLATES));
|
|
1972
991
|
/**
|
|
@@ -2365,7 +1384,7 @@ async function runNpmPublishInitial(input = {}) {
|
|
|
2365
1384
|
const dryRun = input.dryRun ?? false;
|
|
2366
1385
|
const otp = input.otp;
|
|
2367
1386
|
const env = input.env ?? process.env;
|
|
2368
|
-
const exec = input.exec ?? defaultExec;
|
|
1387
|
+
const exec = input.exec ?? defaultExec$1;
|
|
2369
1388
|
const publishArgs = [
|
|
2370
1389
|
"-r",
|
|
2371
1390
|
"--filter=./packages/*",
|
|
@@ -2441,7 +1460,7 @@ function printNextSteps$1(print, env) {
|
|
|
2441
1460
|
print(" https://www.npmjs.com/settings/~/tokens");
|
|
2442
1461
|
}
|
|
2443
1462
|
}
|
|
2444
|
-
const defaultExec = async (cmd, args, opts) => {
|
|
1463
|
+
const defaultExec$1 = async (cmd, args, opts) => {
|
|
2445
1464
|
const result = spawnSync(cmd, args, {
|
|
2446
1465
|
cwd: opts.cwd,
|
|
2447
1466
|
encoding: "utf8",
|
|
@@ -3292,13 +2311,11 @@ export default defineConfig({
|
|
|
3292
2311
|
* 2. Slug collision — packages/holocron-plugin-<slug>/ must not exist.
|
|
3293
2312
|
* 3. Capability sanity — must be one of the 14 known keys; warn for
|
|
3294
2313
|
* many-cardinality caps.
|
|
3295
|
-
* 4.
|
|
3296
|
-
* (Phase B; Phase A takes fully-populated input).
|
|
3297
|
-
* 5. Generate — for each template, write to
|
|
2314
|
+
* 4. Generate — for each template, write to
|
|
3298
2315
|
* packages/holocron-plugin-<slug>/<path>.
|
|
3299
|
-
*
|
|
2316
|
+
* 5. Verify (unless --no-verify) — runs pnpm install +
|
|
3300
2317
|
* pnpm --filter <pkg> typecheck lint test.
|
|
3301
|
-
*
|
|
2318
|
+
* 6. Print next steps.
|
|
3302
2319
|
*/
|
|
3303
2320
|
var PluginCreateError = class extends Error {
|
|
3304
2321
|
name = "PluginCreateError";
|
|
@@ -3421,6 +2438,51 @@ function runPluginCreate(input) {
|
|
|
3421
2438
|
}
|
|
3422
2439
|
filesWritten.push(resolvedPath);
|
|
3423
2440
|
}
|
|
2441
|
+
if (!input.dryRun && !input.noVerify) {
|
|
2442
|
+
const execFn = input.exec ?? defaultExec;
|
|
2443
|
+
const pkg = `@theholocron/holocron-plugin-${inputs.slug}`;
|
|
2444
|
+
print("");
|
|
2445
|
+
print(" Verifying scaffold…");
|
|
2446
|
+
try {
|
|
2447
|
+
execFn("pnpm", ["install", "--frozen-lockfile=false"], {
|
|
2448
|
+
cwd,
|
|
2449
|
+
stdio: "inherit"
|
|
2450
|
+
});
|
|
2451
|
+
execFn("pnpm", [
|
|
2452
|
+
"--filter",
|
|
2453
|
+
pkg,
|
|
2454
|
+
"typecheck"
|
|
2455
|
+
], {
|
|
2456
|
+
cwd,
|
|
2457
|
+
stdio: "inherit"
|
|
2458
|
+
});
|
|
2459
|
+
execFn("pnpm", [
|
|
2460
|
+
"--filter",
|
|
2461
|
+
pkg,
|
|
2462
|
+
"lint"
|
|
2463
|
+
], {
|
|
2464
|
+
cwd,
|
|
2465
|
+
stdio: "inherit"
|
|
2466
|
+
});
|
|
2467
|
+
execFn("pnpm", [
|
|
2468
|
+
"--filter",
|
|
2469
|
+
pkg,
|
|
2470
|
+
"test"
|
|
2471
|
+
], {
|
|
2472
|
+
cwd,
|
|
2473
|
+
stdio: "inherit"
|
|
2474
|
+
});
|
|
2475
|
+
print(" ✓ scaffold verified");
|
|
2476
|
+
} catch (err) {
|
|
2477
|
+
print(` ✗ verify failed — ${err instanceof Error ? err.message : String(err)}`);
|
|
2478
|
+
return {
|
|
2479
|
+
status: "fail",
|
|
2480
|
+
packagePath: packageDir,
|
|
2481
|
+
filesWritten,
|
|
2482
|
+
message: "post-scaffold verify failed; inspect output above"
|
|
2483
|
+
};
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
3424
2486
|
if (!input.dryRun) printNextSteps(print, inputs);
|
|
3425
2487
|
return {
|
|
3426
2488
|
status: "ok",
|
|
@@ -3464,6 +2526,12 @@ function defaultWrite(filepath, content) {
|
|
|
3464
2526
|
mkdirSync(path.dirname(filepath), { recursive: true });
|
|
3465
2527
|
writeFileSync(filepath, content, "utf8");
|
|
3466
2528
|
}
|
|
2529
|
+
function defaultExec(cmd, args, opts) {
|
|
2530
|
+
execFileSync(cmd, args, {
|
|
2531
|
+
cwd: opts.cwd,
|
|
2532
|
+
stdio: opts.stdio
|
|
2533
|
+
});
|
|
2534
|
+
}
|
|
3467
2535
|
function printNextSteps(print, inputs) {
|
|
3468
2536
|
print("");
|
|
3469
2537
|
print(` Scaffolded @theholocron/holocron-plugin-${inputs.slug} (18 files).`);
|
|
@@ -3926,33 +2994,6 @@ function labelerConfig() {
|
|
|
3926
2994
|
``
|
|
3927
2995
|
].join("\n");
|
|
3928
2996
|
}
|
|
3929
|
-
const DEPENDABOT_CONFIG = `\
|
|
3930
|
-
# AUTO-GENERATED by holocron — run \`holocron setup\` to regenerate.
|
|
3931
|
-
version: 2
|
|
3932
|
-
updates:
|
|
3933
|
-
- package-ecosystem: npm
|
|
3934
|
-
directory: /
|
|
3935
|
-
schedule:
|
|
3936
|
-
interval: weekly
|
|
3937
|
-
groups:
|
|
3938
|
-
security-patches:
|
|
3939
|
-
applies-to: security-updates
|
|
3940
|
-
patterns:
|
|
3941
|
-
- "*"
|
|
3942
|
-
all-dependencies:
|
|
3943
|
-
update-types:
|
|
3944
|
-
- minor
|
|
3945
|
-
- patch
|
|
3946
|
-
|
|
3947
|
-
- package-ecosystem: github-actions
|
|
3948
|
-
directory: /
|
|
3949
|
-
schedule:
|
|
3950
|
-
interval: weekly
|
|
3951
|
-
groups:
|
|
3952
|
-
all-actions:
|
|
3953
|
-
patterns:
|
|
3954
|
-
- "*"
|
|
3955
|
-
`;
|
|
3956
2997
|
const RULESET_NAME = "holocron-default-branch";
|
|
3957
2998
|
const BALANCED_REPO_SETTINGS = {
|
|
3958
2999
|
allow_squash_merge: true,
|
|
@@ -4162,7 +3203,7 @@ async function runSetup(input) {
|
|
|
4162
3203
|
if (loader.has("source") && effectivePreset !== "none") {
|
|
4163
3204
|
const source = loader.get("source");
|
|
4164
3205
|
steps.push(await runStep("source", "write .github/dependabot.yml", dryRun, async () => {
|
|
4165
|
-
await source.writeRepoFile(".github/dependabot.yml",
|
|
3206
|
+
await source.writeRepoFile(".github/dependabot.yml", dependabot_default);
|
|
4166
3207
|
}));
|
|
4167
3208
|
print(formatStep(steps[steps.length - 1]));
|
|
4168
3209
|
}
|
|
@@ -4943,15 +3984,40 @@ await yargs(hideBin(process.argv)).scriptName("holocron").usage("$0 <command> [o
|
|
|
4943
3984
|
type: "boolean",
|
|
4944
3985
|
default: true,
|
|
4945
3986
|
describe: "Run post-scaffold pnpm install + typecheck + lint + test (default true; --no-verify skips)"
|
|
4946
|
-
}), (argv) => {
|
|
3987
|
+
}), async (argv) => {
|
|
4947
3988
|
try {
|
|
4948
|
-
|
|
3989
|
+
const capabilityKeys = Object.keys(CARDINALITY).join(", ");
|
|
3990
|
+
const needsPrompt = !argv.capability || !argv.vendorEnv || !argv.baseUrl;
|
|
3991
|
+
let capability;
|
|
3992
|
+
let vendorEnv;
|
|
3993
|
+
let baseUrl;
|
|
3994
|
+
if (needsPrompt) {
|
|
3995
|
+
const rl = createInterface({
|
|
3996
|
+
input: stdin,
|
|
3997
|
+
output: stdout
|
|
3998
|
+
});
|
|
3999
|
+
const ask = (question) => new Promise((resolve) => rl.question(` ${question} `, (answer) => resolve(answer.trim())));
|
|
4000
|
+
try {
|
|
4001
|
+
if (!argv.capability) {
|
|
4002
|
+
console.log(` Available capabilities: ${capabilityKeys}`);
|
|
4003
|
+
capability = await ask("Capability:");
|
|
4004
|
+
} else capability = argv.capability;
|
|
4005
|
+
vendorEnv = argv.vendorEnv ? argv.vendorEnv : await ask(`Vendor-native env var for the ${argv.vendor} token (e.g. MYVENDOR_API_KEY):`);
|
|
4006
|
+
baseUrl = argv.baseUrl ? argv.baseUrl : await ask(`REST base URL for the ${argv.vendor} API (e.g. https://api.myvendor.com):`);
|
|
4007
|
+
} finally {
|
|
4008
|
+
rl.close();
|
|
4009
|
+
}
|
|
4010
|
+
} else {
|
|
4011
|
+
capability = argv.capability;
|
|
4012
|
+
vendorEnv = argv.vendorEnv;
|
|
4013
|
+
baseUrl = argv.baseUrl;
|
|
4014
|
+
}
|
|
4949
4015
|
if (runPluginCreate({
|
|
4950
4016
|
slug: argv.slug,
|
|
4951
4017
|
vendorName: argv.vendor,
|
|
4952
|
-
capability
|
|
4953
|
-
vendorEnv
|
|
4954
|
-
baseUrl
|
|
4018
|
+
capability,
|
|
4019
|
+
vendorEnv,
|
|
4020
|
+
baseUrl,
|
|
4955
4021
|
...argv.tokenEnv ? { tokenEnv: argv.tokenEnv } : {},
|
|
4956
4022
|
dryRun: argv.dryRun,
|
|
4957
4023
|
noVerify: !argv.verify,
|