@joshuafolkken/kit 1.1050.0 → 1.1128.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.json +9 -8
- package/.claude/skills/epic-commands/SKILL.md +5 -7
- package/.claude/skills/workflow-commands/SKILL.md +20 -12
- package/.claude/skills/workflow-commands/background-commands.md +36 -84
- package/.claude/skills/workflow-commands/backlogrun-child.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +8 -6
- package/.claude/skills/workflow-commands/backlogrun-progress.md +30 -33
- package/.claude/skills/workflow-commands/backlogrun-steps.md +12 -12
- package/.claude/skills/workflow-commands/backlogrun.md +2 -2
- package/.claude/skills/workflow-commands/chain-rule.md +4 -2
- package/.claude/skills/workflow-commands/delegation.md +3 -3
- package/.claude/skills/workflow-commands/followup-reference.md +1 -1
- package/.claude/skills/workflow-commands/followup.md +7 -3
- package/.claude/skills/workflow-commands/fullrun-steps.md +3 -2
- package/.claude/skills/workflow-commands/fullrun.md +8 -6
- package/.claude/skills/workflow-commands/halfrun.md +19 -21
- package/.claude/skills/workflow-commands/issue-comments.md +1 -1
- package/.claude/skills/workflow-commands/issue-fold-existing.md +10 -10
- package/.claude/skills/workflow-commands/issue-scout.md +1 -1
- package/.claude/skills/workflow-commands/kickoff.md +9 -4
- package/.claude/skills/workflow-commands/latest-gate.md +8 -16
- package/.claude/skills/workflow-commands/needs-human-review.md +1 -1
- package/.claude/skills/workflow-commands/observation-filing.md +3 -3
- package/.claude/skills/workflow-commands/pre-gate-cut.md +4 -8
- package/.claude/skills/workflow-commands/prerequisite.md +1 -1
- package/.claude/skills/workflow-commands/prrun.md +36 -0
- package/.claude/skills/workflow-commands/retrospective.md +1 -1
- package/.claude/skills/workflow-commands/split-assessment.md +4 -18
- package/.claude/skills/workflow-commands/working-tree-hold.md +22 -2
- package/.codex/hooks.json +16 -20
- package/.github/actions/setup-node/action.yml +33 -0
- package/.github/actions/setup-pnpm/action.yml +93 -0
- package/.github/dependabot.yml +5 -1
- package/.github/workflows/auto-tag.yml +2 -3
- package/.github/workflows/ci.yml +31 -134
- package/.github/workflows/dependabot-auto-merge.yml +1 -0
- package/.github/workflows/pr-classification.yml +6 -44
- package/.github/workflows/production.yml +1 -0
- package/.github/workflows/publish.yml +43 -47
- package/.github/workflows/sonar-qube.yml +41 -4
- package/.pnpmfile.mjs +29 -0
- package/AGENTS.md +5 -2
- package/CLAUDE.md +33 -27
- package/GEMINI.md +5 -2
- package/README.md +66 -20
- package/SECURITY.md +37 -6
- package/cspell/index.yaml +6 -1
- package/dist/CLAUDE.basic.md +6 -6
- package/dist/CLAUDE.md +33 -27
- package/dist/CLAUDE.static.md +6 -6
- package/dist/config-merge/index.js +48 -12
- package/dist/hooks/batch-guard.js +4 -4
- package/dist/hooks/{chunk-7VPDUBRN.js → chunk-4JZDP5X5.js} +152 -155
- package/dist/hooks/{chunk-HJIISEAC.js → chunk-5SD2YM7Z.js} +5 -13
- package/dist/hooks/{chunk-NAS4C7GP.js → chunk-77J7IEQM.js} +2 -2
- package/dist/hooks/{chunk-DMQN45FN.js → chunk-7HVB7SZG.js} +3 -3
- package/dist/hooks/{chunk-RLDX5SOC.js → chunk-AIOIOMPX.js} +4413 -1970
- package/dist/hooks/{chunk-5BK3K7V4.js → chunk-M7QKEKWO.js} +873 -2049
- package/dist/hooks/{chunk-WQ4OSBSS.js → chunk-MKVGBQPA.js} +2 -2
- package/dist/hooks/{chunk-EJDX2TOB.js → chunk-NXYMNPUQ.js} +7 -88
- package/dist/hooks/{chunk-NJQOBE6L.js → chunk-QVLT52OV.js} +2 -7
- package/dist/hooks/{chunk-GQ7KP45M.js → chunk-XYUIQOW3.js} +2 -2
- package/dist/hooks/codex-hook-adapter.js +12 -48
- package/dist/hooks/duplicate-read-guard.js +5 -5
- package/dist/hooks/format-edited.js +2 -2
- package/dist/hooks/inputs.json +280 -0
- package/dist/hooks/investigation-guard.js +5 -5
- package/dist/hooks/pretool-guard.js +9 -9
- package/dist/hooks/session-lang.js +0 -1
- package/dist/hooks/stop-guard.js +192 -333
- package/dist/josh.js +240 -148
- package/dist/managed-marker/index.js +2 -1
- package/dist/version/index.js +70 -78
- package/eslint/rules/promise.js +5 -0
- package/eslint/rules/unicorn.js +3 -2
- package/package.json +26 -5
- package/pnpm-workspace.yaml +5 -7
- package/prompts/collaboration-workflow/glossary.md +17 -0
- package/prompts/collaboration-workflow/issue-citation.md +5 -5
- package/prompts/collaboration-workflow/issue-template.md +1 -1
- package/prompts/collaboration-workflow/operating-rules.md +5 -5
- package/prompts/collaboration-workflow/overview.md +13 -1
- package/prompts/collaboration-workflow/principles.md +9 -0
- package/prompts/collaboration-workflow/report-format.md +1 -1
- package/prompts/collaboration-workflow/residency.md +3 -3
- package/prompts/collaboration-workflow/rule-delivery.md +1 -1
- package/prompts/collaboration-workflow/turn-batching.md +3 -3
- package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
- package/prompts/collaboration-workflow/wip-cap.md +25 -22
- package/prompts/collaboration-workflow.md +6 -8
- package/prompts/review-rubric.md +1 -1
- package/prompts/review.md +3 -3
- package/prompts/sonar-hotspot-handling.md +11 -3
- package/prompts/testing-guide.md +3 -3
- package/scripts/adopt/adopt-toolkits.ts +0 -2
- package/scripts/adopt/adopt.ts +0 -2
- package/scripts/agent/agent-argv.ts +0 -2
- package/scripts/agent/agent-diagnostics.ts +1 -1
- package/scripts/agent/agent-role-profile.ts +0 -7
- package/scripts/agent/claude-agent-argv.ts +0 -2
- package/scripts/agent/codex-agent-argv.ts +1 -1
- package/scripts/agent/codex-hooks.ts +92 -0
- package/scripts/agent/interactive-ask.ts +1 -1
- package/scripts/auto-ok/auto-ok-cli.ts +6 -16
- package/scripts/backlog/backlog-arrival.ts +30 -10
- package/scripts/backlog/backlog-budget-cli.ts +15 -16
- package/scripts/backlog/backlog-budget.ts +0 -2
- package/scripts/backlog/backlog-defect-priority.ts +2 -2
- package/scripts/backlog/backlog-drive-cli.ts +10 -8
- package/scripts/backlog/backlog-drive-named-offer.ts +16 -3
- package/scripts/backlog/backlog-drive-named.ts +2 -1
- package/scripts/backlog/backlog-drive.ts +76 -16
- package/scripts/backlog/backlog-named.ts +0 -3
- package/scripts/backlog/backlog-next.ts +9 -15
- package/scripts/backlog/backlog-offer-cli.ts +6 -19
- package/scripts/backlog/backlog-plan-cli.ts +1 -7
- package/scripts/backlog/backlog-plan.ts +30 -19
- package/scripts/backlog/backlog-pool.ts +3 -6
- package/scripts/backlog/backlog-rank.ts +2 -2
- package/scripts/backlog/backlog-ready.ts +39 -10
- package/scripts/backlog/backlog-scope.ts +1 -3
- package/scripts/backlog/backlog-stalled-detect.ts +2 -2
- package/scripts/backlog/backlog-stalled.ts +0 -1
- package/scripts/backlog/backlog-waves.ts +5 -2
- package/scripts/behavior/behavior-cli.ts +1 -1
- package/scripts/build/build-codex-hooks.ts +26 -0
- package/scripts/build/build-hooks.ts +85 -9
- package/scripts/build/hook-bundle-stamp.ts +111 -0
- package/scripts/cases/cases-cli.ts +1 -1
- package/scripts/cases/cases-logic.ts +1 -1
- package/scripts/ci/composite-actions.ts +30 -0
- package/scripts/ci/pr-classification.ts +3 -3
- package/scripts/claude/workflow-destination.ts +10 -1
- package/scripts/clone/clone-fingerprint.ts +0 -1
- package/scripts/clone/clone-scan-cli.ts +1 -1
- package/scripts/clone/clone-scan.ts +1 -1
- package/scripts/config-merge/json-format.ts +0 -1
- package/scripts/config-merge/parse-jsonc.ts +33 -3
- package/scripts/config-merge/patch-json-key.ts +13 -6
- package/scripts/config-merge/patch-yaml-list.ts +1 -1
- package/scripts/cost-runtime/codex-usage.ts +2 -9
- package/scripts/cost-runtime/cost-attribute.ts +0 -1
- package/scripts/cost-runtime/cost-cli.ts +3 -10
- package/scripts/cost-runtime/cost-corpus.ts +0 -2
- package/scripts/cost-runtime/cost-format.ts +0 -3
- package/scripts/cost-runtime/cost-pricing.ts +0 -1
- package/scripts/cost-runtime/cost-tokens.ts +0 -1
- package/scripts/delegation/delegation-cli.ts +1 -1
- package/scripts/delegation/delegation-policy.ts +0 -1
- package/scripts/delegation/duplicate-read-guard.ts +0 -8
- package/scripts/delegation/fanout-cli.ts +1 -1
- package/scripts/delegation/fanout.ts +0 -2
- package/scripts/delegation/investigation-reads.ts +1 -164
- package/scripts/discovery/repo-map-logic.ts +0 -1
- package/scripts/discovery/repo-party-cli.ts +1 -1
- package/scripts/doctor/doctor-consumer.ts +6 -10
- package/scripts/doctor/doctor-io.ts +9 -13
- package/scripts/doctor/doctor-logic.ts +0 -4
- package/scripts/doctor/doctor.ts +14 -9
- package/scripts/document/backlogrun-parent-read-set.ts +12 -1
- package/scripts/document/document-byte-budget.ts +5 -5
- package/scripts/document/document-byte-check.ts +0 -1
- package/scripts/document/document-read-cli.ts +0 -2
- package/scripts/document/document-section-cli.ts +1 -1
- package/scripts/document/document-section.ts +0 -3
- package/scripts/document/edit-files-cli.ts +0 -1
- package/scripts/document/entry-read-budget.ts +21 -7
- package/scripts/document/entry-read-set.ts +32 -8
- package/scripts/document/lane-child-read-set.ts +8 -6
- package/scripts/document/read-files-cli.ts +0 -4
- package/scripts/document/read-set-cli.ts +0 -2
- package/scripts/document/read-set-point-of-use.ts +9 -3
- package/scripts/document/read-set-pricing.ts +0 -1
- package/scripts/document/read-set-trim.ts +4 -2
- package/scripts/epic/epic-add.ts +1 -1
- package/scripts/epic/epic-audit-cli.ts +1 -4
- package/scripts/epic/epic-audit-orphans.ts +1 -3
- package/scripts/epic/epic-audit-rationale.ts +0 -1
- package/scripts/epic/epic-audit-report.ts +0 -2
- package/scripts/epic/epic-audit.ts +8 -22
- package/scripts/epic/epic-bundle-cli.ts +1 -1
- package/scripts/epic/epic-bundle-evidence.ts +0 -1
- package/scripts/epic/epic-bundle-referenced.ts +1 -5
- package/scripts/epic/epic-bundle.ts +0 -4
- package/scripts/epic/epic-busy.ts +4 -5
- package/scripts/epic/epic-candidate-confirm.ts +0 -5
- package/scripts/epic/epic-classify.ts +2 -2
- package/scripts/epic/epic-cli-argv.ts +0 -1
- package/scripts/epic/epic-close-comment.ts +1 -1
- package/scripts/epic/epic-close.ts +5 -2
- package/scripts/epic/epic-cross-repo.ts +2 -4
- package/scripts/epic/epic-decision.ts +0 -1
- package/scripts/epic/epic-fetch.ts +2 -2
- package/scripts/epic/epic-index.ts +2 -3
- package/scripts/epic/epic-issue.ts +1 -15
- package/scripts/epic/epic-lane-offer.ts +9 -8
- package/scripts/epic/epic-nested.ts +1 -1
- package/scripts/epic/epic-next-read.ts +1 -3
- package/scripts/epic/epic-next-views.ts +0 -1
- package/scripts/epic/epic-next.ts +1 -10
- package/scripts/epic/epic-parse.ts +0 -1
- package/scripts/epic/epic-promote.ts +0 -9
- package/scripts/epic/epic-rank.ts +2 -2
- package/scripts/epic/epic-read.ts +1 -2
- package/scripts/epic/epic-reconcile.ts +1 -1
- package/scripts/epic/epic-reference.ts +1 -13
- package/scripts/epic/epic-relation-recheck.ts +1 -1
- package/scripts/epic/epic-relations.ts +1 -1
- package/scripts/epic/epic-remove.ts +1 -1
- package/scripts/epic/epic-report.ts +0 -1
- package/scripts/epic/epic-run.ts +2 -3
- package/scripts/epic/epic-shape.ts +1 -1
- package/scripts/epic/epic-solo-stale.ts +107 -0
- package/scripts/epic/epic-solo.ts +3 -2
- package/scripts/epic/epic-triage.ts +1 -1
- package/scripts/epic/epic-validate.ts +1 -1
- package/scripts/epic/epic.ts +1 -1
- package/scripts/exports/unused-members-cli.ts +53 -0
- package/scripts/{git → followup}/followup-issue-number.ts +1 -6
- package/scripts/{git → followup}/git-followup-cleanup.ts +2 -1
- package/scripts/{git → followup}/git-followup-finish.ts +1 -3
- package/scripts/{git → followup}/git-followup-flush.ts +2 -2
- package/scripts/{git → followup}/git-followup-issue-close.ts +2 -2
- package/scripts/{git → followup}/git-followup-label.ts +4 -4
- package/scripts/followup/git-followup-merged.ts +112 -0
- package/scripts/{git → followup}/git-followup-pending.ts +1 -1
- package/scripts/{git → followup}/git-followup-workflow.ts +19 -11
- package/scripts/{git → followup}/git-pr-followup-wrapup.ts +9 -3
- package/scripts/{git → followup}/git-pr-followup.ts +53 -16
- package/scripts/gate/core-budget.ts +3 -9
- package/scripts/gate/gate-plan.ts +7 -4
- package/scripts/gate/gate-report.ts +0 -6
- package/scripts/gate/gate-tree.ts +1 -1
- package/scripts/gate/pre-commit-type-check.ts +0 -6
- package/scripts/gate/project-checks.ts +7 -8
- package/scripts/gate/scoped-green.ts +0 -1
- package/scripts/gate/type-check-step.ts +1 -1
- package/scripts/gate/verification-gate.ts +0 -2
- package/scripts/gh/fix-gh-packages.ts +15 -12
- package/scripts/gh/gh-spawn.ts +2 -2
- package/scripts/{git → gh}/git-ai-review-scan.ts +1 -5
- package/scripts/{git → gh}/git-gh-check.ts +2 -1
- package/scripts/{git → gh}/git-gh-exec.ts +1 -1
- package/scripts/{git → gh}/git-gh-failure.ts +1 -1
- package/scripts/{git → gh}/git-gh-helpers.ts +0 -1
- package/scripts/{git → gh}/git-gh-issue-list.ts +13 -10
- package/scripts/{git → gh}/git-gh-issue-read.ts +1 -1
- package/scripts/{git → gh}/git-gh-issue-rest.ts +6 -3
- package/scripts/{git → gh}/git-gh-issue-write.ts +4 -1
- package/scripts/{git → gh}/git-gh-pr-auto-merge.ts +4 -1
- package/scripts/{git → gh}/git-gh-pr-read.ts +24 -0
- package/scripts/{git → gh}/git-gh-pr-rest.ts +5 -2
- package/scripts/{git → gh}/git-gh-pr-review.ts +2 -2
- package/scripts/{git → gh}/git-gh-pr-rollup.ts +1 -3
- package/scripts/{git → gh}/git-gh-pr.ts +3 -1
- package/scripts/{git → gh}/git-pr-ai-review.ts +2 -5
- package/scripts/{git → gh}/git-pr-checks-eval.ts +0 -10
- package/scripts/{git → gh}/git-pr-checks-parse.ts +4 -20
- package/scripts/{git → gh}/git-pr-checks.ts +2 -1
- package/scripts/{git → gh}/git-pr-coderabbit.ts +2 -5
- package/scripts/{git → gh}/git-pr-confirmation.ts +1 -3
- package/scripts/{git → gh}/git-pr-managed-config.ts +2 -3
- package/scripts/{git → gh}/git-pr.ts +3 -3
- package/scripts/git/changed-file-scope.ts +0 -1
- package/scripts/git/git-branch.ts +3 -6
- package/scripts/git/git-command.ts +6 -1
- package/scripts/git/git-commit.ts +1 -1
- package/scripts/git/git-common-directory.ts +80 -24
- package/scripts/git/git-error.ts +66 -9
- package/scripts/git/git-issue.ts +1 -1
- package/scripts/git/git-preflight.ts +2 -2
- package/scripts/git/git-prompt.ts +6 -31
- package/scripts/git/git-push.ts +1 -1
- package/scripts/git/git-spawn-sync.ts +65 -0
- package/scripts/git/git-spawn.ts +5 -4
- package/scripts/git/git-staging.ts +1 -0
- package/scripts/git/git-status.ts +1 -1
- package/scripts/git/git-workflow.ts +1 -1
- package/scripts/git/gone-branch.ts +1 -0
- package/scripts/git/listing-cutoff.ts +1 -1
- package/scripts/git/main-merge.ts +1 -1
- package/scripts/git/main-sync.ts +19 -1
- package/scripts/git/parse-json-array.ts +0 -3
- package/scripts/git/repository-lock.ts +16 -16
- package/scripts/git/{git-stash.ts → stash/git-stash.ts} +1 -1
- package/scripts/git/{stash-pop-args.ts → stash/stash-pop-args.ts} +2 -7
- package/scripts/git/{stash-pop-cli.ts → stash/stash-pop-cli.ts} +0 -1
- package/scripts/git/{stash-sweep-lock.ts → stash/stash-sweep-lock.ts} +3 -3
- package/scripts/hooks/codex-hook-adapter.ts +0 -1
- package/scripts/hooks/edited-cspell.ts +1 -1
- package/scripts/hooks/format-edited-file.ts +2 -0
- package/scripts/hooks/pre-push-unit.ts +0 -4
- package/scripts/hooks/pretool-guard.ts +22 -4
- package/scripts/hooks/reserved-run.ts +1 -1
- package/scripts/hooks/step-zero-notice.ts +76 -0
- package/scripts/hooks/stop-guard.ts +47 -21
- package/scripts/init/claude-plugin-config.ts +4 -5
- package/scripts/init/hook-command-rewrite.ts +16 -8
- package/scripts/init/hook-launch.ts +41 -15
- package/scripts/init/init-basic.ts +2 -5
- package/scripts/init/init-file-action.ts +54 -0
- package/scripts/init/init-logic-migrate.ts +35 -17
- package/scripts/init/init-logic-secretlint.ts +1 -1
- package/scripts/init/init-logic.ts +10 -19
- package/scripts/init/init.ts +11 -71
- package/scripts/init/kit-written-paths.ts +2 -0
- package/scripts/init/project-profile.ts +9 -17
- package/scripts/init/start-exec.ts +1 -1
- package/scripts/init/start-setup-pr.ts +6 -6
- package/scripts/init/start-steps.ts +3 -1
- package/scripts/issue/behavior-change-lint.ts +0 -1
- package/scripts/issue/defect-rate-cli.ts +64 -23
- package/scripts/issue/defect-rate.ts +1 -2
- package/scripts/{git → issue}/git-next-issues.ts +3 -3
- package/scripts/issue/issue-backlinks-cli.ts +1 -5
- package/scripts/issue/issue-backlinks.ts +7 -14
- package/scripts/issue/issue-cite-cli.ts +2 -6
- package/scripts/issue/issue-cite.ts +12 -8
- package/scripts/issue/issue-classification.ts +1 -9
- package/scripts/issue/issue-closing-pr.ts +4 -4
- package/scripts/issue/issue-comment-cli.ts +2 -2
- package/scripts/issue/issue-file-cli.ts +5 -5
- package/scripts/issue/issue-file.ts +7 -14
- package/scripts/issue/issue-fold-cli.ts +1 -1
- package/scripts/issue/issue-fold-existing-cli.ts +1 -1
- package/scripts/{git → issue}/issue-labels.ts +8 -0
- package/scripts/issue/issue-lint-cli.ts +1 -1
- package/scripts/issue/issue-merged.ts +2 -2
- package/scripts/{git → issue}/issue-rank.ts +1 -1
- package/scripts/issue/issue-read-cli.ts +8 -47
- package/scripts/issue/issue-read.ts +0 -2
- package/scripts/issue/issue-report-failures.ts +80 -0
- package/scripts/issue/issue-scout-cli.ts +1 -7
- package/scripts/issue/issue-scout-closed.ts +2 -2
- package/scripts/issue/issue-scout.ts +0 -2
- package/scripts/issue/issue-state-cli.ts +5 -46
- package/scripts/issue/issue-state.ts +1 -5
- package/scripts/issue/markdown-section.ts +21 -6
- package/scripts/issue/measure-rerun-cli.ts +74 -15
- package/scripts/issue/reproduction-measure.ts +1 -1
- package/scripts/josh/cli-body.ts +1 -1
- package/scripts/josh/file-map-stamp.ts +0 -3
- package/scripts/josh/josh-command-map.ts +2 -0
- package/scripts/josh/josh-commands-ai.ts +9 -102
- package/scripts/josh/josh-commands-backlog.ts +5 -1
- package/scripts/josh/josh-commands-development.ts +8 -1
- package/scripts/josh/josh-commands-issue.ts +2 -2
- package/scripts/josh/josh-commands-maintenance.ts +7 -0
- package/scripts/josh/josh-commands-project.ts +7 -1
- package/scripts/josh/josh-commands-run.ts +114 -0
- package/scripts/josh/josh-commands-versioning.ts +8 -0
- package/scripts/josh/josh-commands-workflow.ts +3 -3
- package/scripts/josh/path-decision.ts +0 -3
- package/scripts/josh/process-owner.ts +16 -0
- package/scripts/josh/run-github-prerequisite.ts +3 -6
- package/scripts/josh/session-language-cli.ts +0 -1
- package/scripts/lane/lane-await.ts +46 -19
- package/scripts/lane/lane-capacity.ts +6 -3
- package/scripts/lane/lane-child-invocation.ts +20 -7
- package/scripts/lane/lane-cli.ts +1 -4
- package/scripts/lane/lane-close.ts +5 -4
- package/scripts/lane/lane-dispatch.ts +3 -4
- package/scripts/lane/lane-environment.ts +0 -9
- package/scripts/lane/lane-handoff.ts +38 -0
- package/scripts/lane/lane-launch-cli.ts +31 -27
- package/scripts/lane/lane-open.ts +0 -3
- package/scripts/lane/lane-output.ts +0 -1
- package/scripts/lane/lane-registry.ts +9 -0
- package/scripts/lane/openai-lane-ship.ts +2 -0
- package/scripts/lane/openai-lane-supervisor-decision.ts +2 -1
- package/scripts/lane/openai-lane-supervisor.ts +6 -4
- package/scripts/lane/openai-review-broker.ts +7 -1
- package/scripts/lib/bounded-pool.ts +1 -0
- package/scripts/lib/cli-flags.ts +31 -2
- package/scripts/lib/error-message.ts +12 -1
- package/scripts/lib/json-value.ts +5 -4
- package/scripts/lib/poll.ts +3 -1
- package/scripts/lib/timed-fetch.ts +15 -0
- package/scripts/lib/timeouts.ts +13 -0
- package/scripts/{yaml → lib}/yaml-document.ts +3 -1
- package/scripts/{bytes → lines}/bytes-command.ts +0 -2
- package/scripts/lines/line-targets.ts +0 -11
- package/scripts/lines/lines-command.ts +5 -4
- package/scripts/lint/lint-related-scope.ts +0 -1
- package/scripts/lint/lint-related.ts +1 -1
- package/scripts/{git → notify}/telegram-notify.ts +2 -2
- package/scripts/{git → notify}/telegram-test.ts +4 -4
- package/scripts/observations/observation-ledger-home.ts +0 -1
- package/scripts/observations/observation-ledger-line.ts +0 -1
- package/scripts/observations/observation-ledger-migrate.ts +1 -1
- package/scripts/observations/observations-flush-landing.ts +3 -3
- package/scripts/observations/observations-flush.ts +2 -2
- package/scripts/overrides/lockfile-overrides.ts +1 -1
- package/scripts/overrides/overrides-logic.ts +1 -1
- package/scripts/package/package-scout-cli.ts +2 -7
- package/scripts/package/package-scout.ts +0 -2
- package/scripts/propagate/propagate-git-failure.ts +0 -1
- package/scripts/propagate/propagate-git.ts +3 -10
- package/scripts/propagate/propagate-publish.ts +2 -3
- package/scripts/propagate/propagate-run.ts +0 -2
- package/scripts/propagate/propagate-steps.ts +3 -5
- package/scripts/propagate/propagate-targets.ts +0 -4
- package/scripts/propagate/propagate.ts +0 -4
- package/scripts/refactor/import-graph.ts +0 -1
- package/scripts/refactor/refactor-lint.ts +0 -2
- package/scripts/refactor/refactor-scan.ts +2 -2
- package/scripts/refactor/refactor-targets.ts +0 -1
- package/scripts/registry-migration/migrate-logic.ts +28 -21
- package/scripts/registry-migration/migrate.ts +25 -14
- package/scripts/release/github-release-cli.ts +19 -6
- package/scripts/release/github-release-environment.ts +46 -0
- package/scripts/release/github-release.ts +151 -94
- package/scripts/release/release-history.ts +0 -1
- package/scripts/release/release-plan.ts +0 -1
- package/scripts/release/release-publish.ts +38 -5
- package/scripts/release/release-scope-cli.ts +1 -2
- package/scripts/release/release-tag.ts +2 -4
- package/scripts/release/release-worktree.ts +97 -2
- package/scripts/repo/auto-merge-setting-logic.ts +1 -4
- package/scripts/repo/repo-setting.ts +1 -1
- package/scripts/repo/repository-labels.ts +3 -3
- package/scripts/repo/required-checks-logic.ts +206 -0
- package/scripts/repo/required-checks-report.ts +71 -0
- package/scripts/repo/ruleset-check-cli.ts +53 -0
- package/scripts/repo/ruleset-check.ts +147 -0
- package/scripts/report/report-lint-cli.ts +0 -4
- package/scripts/review/disposition-cli.ts +1 -1
- package/scripts/review/live-evidence.ts +1 -1
- package/scripts/review/review-attest-cli.ts +0 -6
- package/scripts/review/review-attest.ts +4 -16
- package/scripts/review/review-brief-cli.ts +23 -6
- package/scripts/review/review-brief.ts +21 -8
- package/scripts/review/review-checkout.ts +3 -2
- package/scripts/review/review-diff-parts.ts +89 -0
- package/scripts/review/review-diff-write.ts +97 -0
- package/scripts/review/review-finding-ledger.ts +0 -1
- package/scripts/review/review-record-cli.ts +10 -17
- package/scripts/review/review-record.ts +0 -1
- package/scripts/review/review-round2-cli.ts +1 -1
- package/scripts/review/review-stamps.ts +0 -3
- package/scripts/review/review-tree.ts +14 -2
- package/scripts/rules/decision-oracle-stage.ts +18 -0
- package/scripts/rules/decision-oracle.ts +10 -7
- package/scripts/rules/delivered-rules.ts +9 -1
- package/scripts/rules/destructive-command.ts +119 -0
- package/scripts/rules/direct-filing.ts +1 -1
- package/scripts/rules/early-heartbeat.ts +4 -3
- package/scripts/rules/file-body.ts +0 -3
- package/scripts/rules/filing-cap.ts +0 -2
- package/scripts/rules/gh-api.ts +7 -2
- package/scripts/rules/git-argv.ts +18 -7
- package/scripts/rules/git-force.ts +0 -2
- package/scripts/rules/implementation-cut.ts +0 -1
- package/scripts/rules/index-guard.ts +71 -0
- package/scripts/rules/issue-citation.ts +50 -25
- package/scripts/rules/lane-background.ts +15 -7
- package/scripts/rules/lane-park.ts +22 -6
- package/scripts/rules/last-prompt.ts +1 -0
- package/scripts/rules/oracle-consulted.ts +1 -1
- package/scripts/rules/oracle-firing.ts +1 -0
- package/scripts/rules/oracle-list-cli.ts +0 -3
- package/scripts/rules/permission-guards.ts +14 -0
- package/scripts/rules/protected-files.ts +74 -0
- package/scripts/rules/reply-language.ts +1 -1
- package/scripts/rules/rule-body-guard.ts +0 -3
- package/scripts/rules/rule-value-cli.ts +0 -1
- package/scripts/rules/shell-body-trigger.ts +0 -1
- package/scripts/rules/shell-segments.ts +0 -1
- package/scripts/rules/stop-rules.ts +20 -9
- package/scripts/rules/tail-commands.ts +1 -1
- package/scripts/rules/test-declared-commit.ts +1 -1
- package/scripts/rules/third-party-write.ts +0 -1
- package/scripts/rules/worktree-guard.ts +26 -9
- package/scripts/run/run-carry-args.ts +8 -12
- package/scripts/run/run-carry-cli.ts +0 -2
- package/scripts/run/run-carry-stash.ts +2 -2
- package/scripts/run/run-carry-streak.ts +1 -1
- package/scripts/run/run-cut-args.ts +1 -6
- package/scripts/run/run-cut-cli.ts +0 -7
- package/scripts/run/run-cut.ts +8 -54
- package/scripts/run/run-ending-cli.ts +2 -6
- package/scripts/run/run-ending.ts +1 -4
- package/scripts/run/run-entry-cli.ts +133 -25
- package/scripts/run/run-entry-stop.ts +104 -0
- package/scripts/run/run-entry.ts +0 -1
- package/scripts/run/run-event-cli.ts +0 -2
- package/scripts/run/run-event-follow.ts +1 -0
- package/scripts/run/run-event-render.ts +1 -1
- package/scripts/run/run-event-scope.ts +53 -4
- package/scripts/run/run-event-stream-emit.ts +7 -2
- package/scripts/run/run-event-stream.ts +0 -3
- package/scripts/run/run-event-watch.ts +1 -0
- package/scripts/run/run-halfrun-resume.ts +20 -7
- package/scripts/run/run-headless.ts +2 -2
- package/scripts/run/run-hold-cli.ts +33 -10
- package/scripts/run/run-hold.ts +29 -6
- package/scripts/run/run-issue-number.ts +1 -1
- package/scripts/run/run-liveness-cli.ts +2 -6
- package/scripts/run/run-liveness.ts +2 -3
- package/scripts/run/run-merge-cli.ts +7 -23
- package/scripts/run/run-merge-steps.ts +5 -5
- package/scripts/run/run-merge.ts +1 -1
- package/scripts/run/run-next-cli.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +4 -2
- package/scripts/run/run-preflight.ts +2 -9
- package/scripts/run/run-prep-cli.ts +6 -3
- package/scripts/run/run-prep-locate.ts +1 -1
- package/scripts/run/run-progress-args.ts +20 -4
- package/scripts/run/run-progress-cli.ts +35 -36
- package/scripts/run/run-progress-clock.ts +10 -35
- package/scripts/run/run-progress-config.ts +0 -4
- package/scripts/run/run-progress-read.ts +1 -2
- package/scripts/run/run-progress.ts +1 -2
- package/scripts/run/run-prrun-resume.ts +117 -0
- package/scripts/run/run-report-cli.ts +1 -2
- package/scripts/run/run-report.ts +0 -1
- package/scripts/run/run-retrospective.ts +1 -1
- package/scripts/run/run-review-cli.ts +0 -3
- package/scripts/run/run-review-steps.ts +2 -0
- package/scripts/run/run-review.ts +0 -2
- package/scripts/run/run-ship-cli.ts +29 -19
- package/scripts/run/run-ship-detach.ts +1 -0
- package/scripts/run/run-ship-next.ts +106 -0
- package/scripts/run/run-ship-preflight.ts +1 -1
- package/scripts/run/run-ship-probe.ts +4 -1
- package/scripts/run/run-ship-return.ts +8 -3
- package/scripts/run/run-ship-review-steps.ts +18 -4
- package/scripts/run/run-ship-review.ts +11 -0
- package/scripts/run/run-ship-scoped.ts +1 -0
- package/scripts/run/run-ship-steps.ts +1 -1
- package/scripts/run/run-ship.ts +0 -1
- package/scripts/run/run-stage-read.ts +62 -0
- package/scripts/run/run-stage.ts +160 -0
- package/scripts/run/run-status-cli.ts +3 -16
- package/scripts/run/run-step-cli.ts +21 -14
- package/scripts/run/run-step.ts +1 -1
- package/scripts/run/run-stop-notify.ts +1 -3
- package/scripts/run/run-stranded-cli.ts +0 -4
- package/scripts/run/run-stranded-detect.ts +2 -2
- package/scripts/run/run-tail-cli.ts +17 -11
- package/scripts/run/run-tail.ts +2 -0
- package/scripts/run/run-tidy-lanes.ts +6 -2
- package/scripts/run/run-tidy-stashes.ts +12 -12
- package/scripts/run/run-wake-cli.ts +4 -13
- package/scripts/run/run-wake-loop.ts +2 -2
- package/scripts/run/run-wake.ts +2 -4
- package/scripts/run/run-watcher-guard-cli.ts +0 -4
- package/scripts/run/run-watcher-guard.ts +18 -12
- package/scripts/run/run-watcher-hook.ts +1 -1
- package/scripts/safe-chain/ci-installer-pin.ts +11 -5
- package/scripts/safe-chain/pack-hook.ts +92 -0
- package/scripts/safe-chain/project-config.ts +1 -1
- package/scripts/security/security-audit-provision-logic.ts +0 -1
- package/scripts/security/security-audit-provision.ts +3 -2
- package/scripts/security/security-audit.ts +0 -1
- package/scripts/security/security-updates-logic.ts +0 -1
- package/scripts/sonar/sonar-hotspots-cli.ts +10 -52
- package/scripts/sonar/sonar-hotspots.ts +0 -1
- package/scripts/sonar/sonar-new-code-cli.ts +150 -0
- package/scripts/sonar/sonar-new-code.ts +79 -0
- package/scripts/sonar/sonar-project.ts +97 -0
- package/scripts/split/split-assess-cli.ts +1 -1
- package/scripts/split/split-assess.ts +2 -5
- package/scripts/sync/managed-config-scope-cli.ts +1 -1
- package/scripts/sync/skill-migration.ts +0 -1
- package/scripts/sync/sync-ai-files.ts +4 -0
- package/scripts/sync/sync-hook-safety.ts +2 -3
- package/scripts/sync/sync.ts +1 -8
- package/scripts/sync/template-source-logic.ts +0 -1
- package/scripts/sync/workflow-pin-logic.ts +16 -28
- package/scripts/test/test-declared-changed.ts +13 -16
- package/scripts/test/test-declared-logic.ts +0 -1
- package/scripts/test/test-declared.ts +3 -9
- package/scripts/test/test-red-commit.ts +2 -2
- package/scripts/test/test-red.ts +14 -7
- package/scripts/test/test-type-logic.ts +1 -1
- package/scripts/test/unit-worker-share.ts +7 -16
- package/scripts/time-runtime/time-batch-guard.ts +1 -2
- package/scripts/time-runtime/time-bundle-call.ts +0 -1
- package/scripts/time-runtime/time-bundles.ts +0 -4
- package/scripts/time-runtime/time-density-hook.ts +0 -2
- package/scripts/time-runtime/time-followup-stage.ts +1 -1
- package/scripts/time-runtime/time-format.ts +0 -73
- package/scripts/time-runtime/time-round-trips.ts +0 -4
- package/scripts/time-runtime/time-single-check.ts +1 -1
- package/scripts/time-runtime/time-spans.ts +1 -1
- package/scripts/time-runtime/time-transcript-line.ts +1 -2
- package/scripts/ui/ui-routes-cli.ts +0 -5
- package/scripts/ui/ui-routes.ts +0 -5
- package/scripts/version/effective-upstream.ts +2 -2
- package/scripts/version/latest-corepack.ts +7 -9
- package/scripts/version/latest-scope-cli.ts +0 -2
- package/scripts/version/latest-update.ts +0 -2
- package/scripts/version/npm-registry.ts +2 -2
- package/scripts/version/publishable-range-check.ts +1 -1
- package/scripts/version/release-hold.ts +0 -4
- package/scripts/version/running-binary.ts +2 -2
- package/scripts/version/version-check-logic.ts +0 -2
- package/scripts/version/version-commands.ts +11 -1
- package/scripts/version/version-remote.ts +3 -3
- package/scripts/version/version-targets.ts +4 -4
- package/templates/CLAUDE.basic.md +6 -6
- package/templates/sonar-project.properties +28 -1
- package/templates/workflows/ci.yml +16 -82
- package/templates/workflows/dependabot-auto-merge.yml +6 -3
- package/templates/workflows/github-release.yml +79 -0
- package/tsconfig.sonar.json +4 -22
- package/prompts/collaboration-workflow/cross-repo-epic.md +0 -5
- package/prompts/collaboration-workflow/epic-audit.md +0 -5
- package/prompts/collaboration-workflow/epic-bundle.md +0 -5
- package/scripts/init/plugin-install-hint.ts +0 -47
- package/scripts/version/parse-json.ts +0 -13
- /package/scripts/{git → followup}/git-followup-stages.ts +0 -0
- /package/scripts/{git → gh}/git-gh-api-path.ts +0 -0
- /package/scripts/{git → gh}/git-gh-command.ts +0 -0
- /package/scripts/{git → gh}/git-gh-issue.ts +0 -0
- /package/scripts/{git → gh}/git-gh-pr-snapshot.ts +0 -0
- /package/scripts/{git → gh}/git-gh-reachability.ts +0 -0
- /package/scripts/{git → gh}/git-gh-repo.ts +0 -0
- /package/scripts/{git → gh}/git-gh-rest-state.ts +0 -0
- /package/scripts/{git → gh}/git-pr-checks-watch.ts +0 -0
- /package/scripts/{git → gh}/git-pr-error.ts +0 -0
- /package/scripts/{git → gh}/git-pr-messages.ts +0 -0
- /package/scripts/{git → gh}/github-issue-url.ts +0 -0
- /package/scripts/git/{stash-orphans.ts → stash/stash-orphans.ts} +0 -0
- /package/scripts/{git → issue}/issue-reference.ts +0 -0
- /package/scripts/{git → lib}/animation-helpers.ts +0 -0
- /package/scripts/{git → lib}/git-animation.ts +0 -0
- /package/scripts/{git → notify}/git-notify.ts +0 -0
- /package/scripts/{git → notify}/telegram-test-logic.ts +0 -0
|
@@ -2,15 +2,15 @@ import { setTimeout } from 'node:timers/promises'
|
|
|
2
2
|
import semver from 'semver'
|
|
3
3
|
import { z } from 'zod'
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
const WORKFLOW_JOBS_URL = 'https://api.github.com/repos/joshuafolkken/kit/actions/runs'
|
|
5
|
+
const API_ROOT = 'https://api.github.com/repos'
|
|
6
|
+
const LATEST_PATH = '/releases/latest'
|
|
7
|
+
const REPOSITORY_PATTERN = /^[\w.-]+\/[\w.-]+$/u
|
|
9
8
|
const TAG_PATTERN = /^v\d+\.\d+\.\d+(?:[.-][0-9A-Za-z.-]+)?$/u
|
|
10
9
|
const REQUEST_TIMEOUT_MS = 30_000
|
|
11
10
|
const NOT_FOUND_STATUS = 404
|
|
12
|
-
//
|
|
13
|
-
|
|
11
|
+
// A job skipped by its `if:` (or neutral) belongs to a run that succeeded; counting it would skip a
|
|
12
|
+
// lower tag whose release is still on its way.
|
|
13
|
+
const FAILED_CONCLUSIONS = new Set(['failure', 'cancelled', 'timed_out', 'startup_failure'])
|
|
14
14
|
const POLL_INTERVAL_MS = 30_000
|
|
15
15
|
const MAX_WAIT_ATTEMPTS = 120
|
|
16
16
|
const RELEASE_SCHEMA = z.object({ tag_name: z.string().min(1) })
|
|
@@ -23,16 +23,42 @@ const JOB_SCHEMA = z.object({
|
|
|
23
23
|
})
|
|
24
24
|
const RUNS_SCHEMA = z.object({ workflow_runs: z.array(RUN_SCHEMA) })
|
|
25
25
|
const JOBS_SCHEMA = z.object({ jobs: z.array(JOB_SCHEMA) })
|
|
26
|
-
const PREREQUISITES = ['publish-github', 'publish-npm', 'update-production']
|
|
27
26
|
|
|
28
27
|
type ReleaseRequest = (url: string, init: RequestInit) => Promise<Response>
|
|
29
28
|
type Wait = () => Promise<void>
|
|
30
29
|
|
|
31
|
-
|
|
30
|
+
// What differs between repositories. `start_tag` is the last tag that predates automatic releases;
|
|
31
|
+
// without it the latest existing release is the floor. `workflow` names the publish workflow whose
|
|
32
|
+
// failed run lets a lower tag be skipped, and `jobs` the jobs in it that count (empty: every job).
|
|
33
|
+
interface ReleaseSettings {
|
|
34
|
+
repository: string
|
|
35
|
+
start_tag?: string | undefined
|
|
36
|
+
workflow?: string | undefined
|
|
37
|
+
jobs?: ReadonlyArray<string> | undefined
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
interface PublishOptions extends ReleaseSettings {
|
|
32
41
|
tags?: ReadonlyArray<string>
|
|
33
42
|
wait?: Wait
|
|
34
43
|
}
|
|
35
44
|
|
|
45
|
+
interface Client {
|
|
46
|
+
request: ReleaseRequest
|
|
47
|
+
token: string
|
|
48
|
+
url: string
|
|
49
|
+
workflow: string | undefined
|
|
50
|
+
jobs: ReadonlyArray<string>
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// `fallback` answers when no tag sits between the floor and the target; without one the floor itself
|
|
54
|
+
// is the latest release and the answer.
|
|
55
|
+
interface Ladder {
|
|
56
|
+
tags: ReadonlyArray<string>
|
|
57
|
+
floor: string | undefined
|
|
58
|
+
fallback?: () => Promise<string>
|
|
59
|
+
wait: Wait
|
|
60
|
+
}
|
|
61
|
+
|
|
36
62
|
function request_options(token: string, method: string, body?: object): RequestInit {
|
|
37
63
|
return {
|
|
38
64
|
method,
|
|
@@ -46,21 +72,22 @@ function request_options(token: string, method: string, body?: object): RequestI
|
|
|
46
72
|
}
|
|
47
73
|
}
|
|
48
74
|
|
|
75
|
+
async function api_get(client: Client, path: string): Promise<Response> {
|
|
76
|
+
return await client.request(`${client.url}${path}`, request_options(client.token, 'GET'))
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function api_post(client: Client, path: string, body: object): Promise<Response> {
|
|
80
|
+
return await client.request(`${client.url}${path}`, request_options(client.token, 'POST', body))
|
|
81
|
+
}
|
|
82
|
+
|
|
49
83
|
async function read_response(response: Response): Promise<unknown> {
|
|
50
84
|
if (!response.ok) throw new Error(`GitHub Releases API returned HTTP ${String(response.status)}`)
|
|
51
85
|
|
|
52
86
|
return await response.json()
|
|
53
87
|
}
|
|
54
88
|
|
|
55
|
-
async function existing_release(
|
|
56
|
-
|
|
57
|
-
token: string,
|
|
58
|
-
tag: string,
|
|
59
|
-
): Promise<boolean> {
|
|
60
|
-
const response = await request(
|
|
61
|
-
`${API_URL}/tags/${encodeURIComponent(tag)}`,
|
|
62
|
-
request_options(token, 'GET'),
|
|
63
|
-
)
|
|
89
|
+
async function existing_release(client: Client, tag: string): Promise<boolean> {
|
|
90
|
+
const response = await api_get(client, `/releases/tags/${encodeURIComponent(tag)}`)
|
|
64
91
|
if (response.status === NOT_FOUND_STATUS) return false
|
|
65
92
|
|
|
66
93
|
RELEASE_SCHEMA.parse(await read_response(response))
|
|
@@ -68,153 +95,183 @@ async function existing_release(
|
|
|
68
95
|
return true
|
|
69
96
|
}
|
|
70
97
|
|
|
71
|
-
async function previous_tag(
|
|
72
|
-
const response = await
|
|
73
|
-
const release = RELEASE_SCHEMA.parse(await read_response(response))
|
|
98
|
+
async function previous_tag(client: Client): Promise<string> {
|
|
99
|
+
const response = await api_get(client, LATEST_PATH)
|
|
74
100
|
|
|
75
|
-
return
|
|
101
|
+
return RELEASE_SCHEMA.parse(await read_response(response)).tag_name
|
|
76
102
|
}
|
|
77
103
|
|
|
78
|
-
function
|
|
104
|
+
async function latest_release(client: Client): Promise<string | undefined> {
|
|
105
|
+
const response = await api_get(client, LATEST_PATH)
|
|
106
|
+
if (response.status === NOT_FOUND_STATUS) return undefined
|
|
107
|
+
|
|
108
|
+
return RELEASE_SCHEMA.parse(await read_response(response)).tag_name
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function predecessor(
|
|
112
|
+
tags: ReadonlyArray<string>,
|
|
113
|
+
target: string,
|
|
114
|
+
floor: string | undefined,
|
|
115
|
+
): string | undefined {
|
|
79
116
|
return tags
|
|
80
117
|
.filter(
|
|
81
|
-
(tag) =>
|
|
118
|
+
(tag) =>
|
|
119
|
+
semver.valid(tag) &&
|
|
120
|
+
(floor === undefined || semver.gt(tag, floor)) &&
|
|
121
|
+
semver.lt(tag, target),
|
|
82
122
|
)
|
|
83
123
|
.toSorted((left, right) => semver.compare(right, left))[0]
|
|
84
124
|
}
|
|
85
125
|
|
|
86
|
-
function is_failed_job(job: z.infer<typeof JOB_SCHEMA>): boolean {
|
|
87
|
-
if (job.status !== 'completed' || job.conclusion
|
|
126
|
+
function is_failed_job(job: z.infer<typeof JOB_SCHEMA>, names: ReadonlyArray<string>): boolean {
|
|
127
|
+
if (job.status !== 'completed' || !FAILED_CONCLUSIONS.has(job.conclusion ?? '')) return false
|
|
128
|
+
if (names.length === 0) return true
|
|
88
129
|
|
|
89
|
-
return
|
|
130
|
+
return names.some((name) => job.name === name || job.name.startsWith(`${name} /`))
|
|
90
131
|
}
|
|
91
132
|
|
|
92
|
-
function
|
|
93
|
-
|
|
94
|
-
}
|
|
133
|
+
async function failed_publication(client: Client, tag: string): Promise<boolean> {
|
|
134
|
+
if (client.workflow === undefined) return false
|
|
95
135
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
token: string,
|
|
99
|
-
tag: string,
|
|
100
|
-
): Promise<boolean> {
|
|
101
|
-
const runs_response = await request(WORKFLOW_RUNS_URL, request_options(token, 'GET'))
|
|
136
|
+
const workflow = encodeURIComponent(client.workflow)
|
|
137
|
+
const runs_response = await api_get(client, `/actions/workflows/${workflow}/runs?per_page=100`)
|
|
102
138
|
const runs = RUNS_SCHEMA.parse(await read_response(runs_response)).workflow_runs
|
|
103
139
|
const run = runs.find((item) => item.display_title === `Publish ${tag}`)
|
|
104
140
|
if (!run) return false
|
|
105
141
|
|
|
106
|
-
const
|
|
107
|
-
const
|
|
142
|
+
const jobs_response = await api_get(client, `/actions/runs/${String(run.id)}/jobs?per_page=100`)
|
|
143
|
+
const { jobs } = JOBS_SCHEMA.parse(await read_response(jobs_response))
|
|
108
144
|
|
|
109
|
-
return
|
|
145
|
+
return jobs.some((job) => is_failed_job(job, client.jobs))
|
|
110
146
|
}
|
|
111
147
|
|
|
112
148
|
async function default_wait(): Promise<void> {
|
|
113
149
|
await setTimeout(POLL_INTERVAL_MS)
|
|
114
150
|
}
|
|
115
151
|
|
|
116
|
-
async function release_state(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
tag: string,
|
|
120
|
-
): Promise<'ready' | 'failed' | 'pending'> {
|
|
121
|
-
if (await existing_release(request, token, tag)) return 'ready'
|
|
122
|
-
if (await failed_publication(request, token, tag)) return 'failed'
|
|
152
|
+
async function release_state(client: Client, tag: string): Promise<'ready' | 'failed' | 'pending'> {
|
|
153
|
+
if (await existing_release(client, tag)) return 'ready'
|
|
154
|
+
if (await failed_publication(client, tag)) return 'failed'
|
|
123
155
|
|
|
124
156
|
return 'pending'
|
|
125
157
|
}
|
|
126
158
|
|
|
127
|
-
async function wait_for_release(
|
|
128
|
-
request: ReleaseRequest,
|
|
129
|
-
token: string,
|
|
130
|
-
tag: string,
|
|
131
|
-
wait: Wait,
|
|
132
|
-
): Promise<boolean> {
|
|
159
|
+
async function wait_for_release(client: Client, tag: string, wait: Wait): Promise<boolean> {
|
|
133
160
|
for (let attempt = 0; attempt < MAX_WAIT_ATTEMPTS; attempt += 1) {
|
|
134
|
-
|
|
161
|
+
// eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
|
|
162
|
+
const state = await release_state(client, tag)
|
|
135
163
|
if (state !== 'pending') return state === 'ready'
|
|
136
164
|
|
|
165
|
+
// eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
|
|
137
166
|
await wait()
|
|
138
167
|
}
|
|
139
168
|
|
|
140
169
|
throw new Error(`Timed out waiting for previous GitHub Release ${tag}`)
|
|
141
170
|
}
|
|
142
171
|
|
|
172
|
+
async function ladder_end(ladder: Ladder): Promise<string | undefined> {
|
|
173
|
+
return ladder.fallback ? await ladder.fallback() : ladder.floor
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// With no floor the repository has no release at all, so no lower tag will ever gain one: the
|
|
177
|
+
// nearest lower tag is the baseline as it stands, and none means notes without a baseline.
|
|
143
178
|
async function baseline_tag(
|
|
144
|
-
|
|
145
|
-
token: string,
|
|
179
|
+
client: Client,
|
|
146
180
|
tag: string,
|
|
147
|
-
|
|
148
|
-
): Promise<string> {
|
|
149
|
-
const prior = predecessor(
|
|
150
|
-
if (
|
|
181
|
+
ladder: Ladder,
|
|
182
|
+
): Promise<string | undefined> {
|
|
183
|
+
const prior = predecessor(ladder.tags, tag, ladder.floor)
|
|
184
|
+
if (ladder.floor === undefined) return prior
|
|
185
|
+
if (!prior) return await ladder_end(ladder)
|
|
186
|
+
|
|
187
|
+
return (await wait_for_release(client, prior, ladder.wait))
|
|
188
|
+
? prior
|
|
189
|
+
: await baseline_tag(client, prior, ladder)
|
|
190
|
+
}
|
|
151
191
|
|
|
152
|
-
|
|
153
|
-
|
|
192
|
+
function assert_older(previous: string | undefined, tag: string): void {
|
|
193
|
+
if (previous !== undefined && !semver.lt(previous, tag)) {
|
|
194
|
+
throw new Error(`Latest release ${previous} is not older than ${tag}`)
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async function build_ladder(client: Client, options: PublishOptions): Promise<Ladder> {
|
|
199
|
+
const tags = options.tags ?? []
|
|
200
|
+
const wait = options.wait ?? default_wait
|
|
201
|
+
const { start_tag } = options
|
|
202
|
+
|
|
203
|
+
if (start_tag !== undefined) {
|
|
204
|
+
return { tags, wait, floor: start_tag, fallback: async () => await previous_tag(client) }
|
|
154
205
|
}
|
|
155
206
|
|
|
156
|
-
return
|
|
207
|
+
return { tags, wait, floor: await latest_release(client) }
|
|
157
208
|
}
|
|
158
209
|
|
|
159
210
|
async function generate_notes(
|
|
160
|
-
|
|
161
|
-
token: string,
|
|
211
|
+
client: Client,
|
|
162
212
|
tag: string,
|
|
163
|
-
previous: string,
|
|
213
|
+
previous: string | undefined,
|
|
164
214
|
): Promise<z.infer<typeof NOTES_SCHEMA>> {
|
|
165
|
-
const response = await
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
configuration_file_path: '.github/release.yml',
|
|
171
|
-
}),
|
|
172
|
-
)
|
|
215
|
+
const response = await api_post(client, '/releases/generate-notes', {
|
|
216
|
+
tag_name: tag,
|
|
217
|
+
...(previous !== undefined && { previous_tag_name: previous }),
|
|
218
|
+
configuration_file_path: '.github/release.yml',
|
|
219
|
+
})
|
|
173
220
|
|
|
174
221
|
return NOTES_SCHEMA.parse(await read_response(response))
|
|
175
222
|
}
|
|
176
223
|
|
|
177
224
|
async function create_release(
|
|
178
|
-
|
|
179
|
-
token: string,
|
|
225
|
+
client: Client,
|
|
180
226
|
tag: string,
|
|
181
|
-
previous: string,
|
|
227
|
+
previous: string | undefined,
|
|
182
228
|
): Promise<void> {
|
|
183
|
-
const notes = await generate_notes(
|
|
184
|
-
const response = await
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
prerelease: false,
|
|
192
|
-
}),
|
|
193
|
-
)
|
|
229
|
+
const notes = await generate_notes(client, tag, previous)
|
|
230
|
+
const response = await api_post(client, '/releases', {
|
|
231
|
+
tag_name: tag,
|
|
232
|
+
name: notes.name,
|
|
233
|
+
body: notes.body,
|
|
234
|
+
draft: false,
|
|
235
|
+
prerelease: false,
|
|
236
|
+
})
|
|
194
237
|
|
|
195
238
|
RELEASE_SCHEMA.parse(await read_response(response))
|
|
196
239
|
}
|
|
197
240
|
|
|
241
|
+
function create_client(request: ReleaseRequest, token: string, settings: ReleaseSettings): Client {
|
|
242
|
+
if (!REPOSITORY_PATTERN.test(settings.repository)) {
|
|
243
|
+
throw new Error(`Invalid repository: ${settings.repository}`)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return {
|
|
247
|
+
request,
|
|
248
|
+
token,
|
|
249
|
+
url: `${API_ROOT}/${settings.repository}`,
|
|
250
|
+
workflow: settings.workflow,
|
|
251
|
+
jobs: settings.jobs ?? [],
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
198
255
|
async function publish(
|
|
199
256
|
request: ReleaseRequest,
|
|
200
257
|
token: string,
|
|
201
258
|
tag: string,
|
|
202
|
-
options: PublishOptions
|
|
259
|
+
options: PublishOptions,
|
|
203
260
|
): Promise<string> {
|
|
204
261
|
if (!TAG_PATTERN.test(tag)) throw new Error(`Invalid release tag: ${tag}`)
|
|
205
|
-
if (await existing_release(request, token, tag)) return 'already-published'
|
|
206
262
|
|
|
207
|
-
const
|
|
263
|
+
const client = create_client(request, token, options)
|
|
264
|
+
if (await existing_release(client, tag)) return 'already-published'
|
|
208
265
|
|
|
209
|
-
|
|
210
|
-
throw new Error(`Latest release ${previous} is not older than ${tag}`)
|
|
211
|
-
}
|
|
266
|
+
const previous = await baseline_tag(client, tag, await build_ladder(client, options))
|
|
212
267
|
|
|
213
|
-
|
|
268
|
+
assert_older(previous, tag)
|
|
269
|
+
await create_release(client, tag, previous)
|
|
214
270
|
|
|
215
|
-
return `published ${tag} from ${previous}`
|
|
271
|
+
return `published ${tag} from ${previous ?? 'the first commit'}`
|
|
216
272
|
}
|
|
217
273
|
|
|
218
274
|
const github_release = { publish }
|
|
219
275
|
|
|
276
|
+
export type { ReleaseSettings }
|
|
220
277
|
export { github_release }
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { git_gh_command } from '#scripts/gh/git-gh-command'
|
|
2
|
+
import { git_pr_checks } from '#scripts/gh/git-pr-checks'
|
|
1
3
|
import { git_command } from '#scripts/git/git-command'
|
|
2
|
-
import { git_gh_command } from '#scripts/git/git-gh-command'
|
|
3
|
-
import { git_pr_checks } from '#scripts/git/git-pr-checks'
|
|
4
4
|
import { git_remote_branch } from '#scripts/git/git-remote-branch'
|
|
5
|
+
import { repository_lock } from '#scripts/git/repository-lock'
|
|
5
6
|
import { write_version } from '#scripts/version/bump-version'
|
|
6
7
|
import { version_targets } from '#scripts/version/version-targets'
|
|
7
8
|
import type { ReleasePlan } from './release-plan'
|
|
@@ -20,6 +21,9 @@ const { PACKAGE_JSON } = version_targets
|
|
|
20
21
|
const SUCCESS_EXIT_CODE = 0
|
|
21
22
|
const FAILURE_EXIT_CODE = 1
|
|
22
23
|
const IGNORE_FOR_RELEASE_LABEL = 'ignore-for-release'
|
|
24
|
+
const RELEASE_LOCK_PREFIX = 'josh-release-lock-'
|
|
25
|
+
// A release waits on CI for minutes, so a second run refuses rather than queueing behind it.
|
|
26
|
+
const RELEASE_LOCK_MAX_WAIT_MS = 0
|
|
23
27
|
|
|
24
28
|
function branch_name_for(version: string): string {
|
|
25
29
|
return `release/v${version}`
|
|
@@ -87,6 +91,14 @@ async function refuse_existing_branch(branch_name: string): Promise<void> {
|
|
|
87
91
|
throw new Error(existing_branch_message(branch_name))
|
|
88
92
|
}
|
|
89
93
|
|
|
94
|
+
// **The leftovers go before the guard asks** (joshuafolkken/kit#3058). A run cut off before its
|
|
95
|
+
// `finally`, or a `worktree add` that failed after creating its branch, leaves a local
|
|
96
|
+
// `release/v<version>` that the guard would otherwise refuse as a release already opened.
|
|
97
|
+
async function clear_the_way(branch_name: string): Promise<void> {
|
|
98
|
+
await release_worktree.clear_leftover()
|
|
99
|
+
await refuse_existing_branch(branch_name)
|
|
100
|
+
}
|
|
101
|
+
|
|
90
102
|
// **No `checkout -b` and no branch guard here** (joshuafolkken/kit#2411). The work tree is already
|
|
91
103
|
// sitting on the release branch — `release_worktree.create` cut it that way — and the guard ran
|
|
92
104
|
// before that creation, because `worktree_add` makes the branch local and `branch_exists` would then
|
|
@@ -121,10 +133,10 @@ async function merge_and_tag(plan: ReleasePlan, branch_name: string): Promise<nu
|
|
|
121
133
|
// branch guard runs before the tree exists, `process.chdir` points the version write and the git
|
|
122
134
|
// commands at the tree, and the `finally` returns to the root and removes the tree — whichever way
|
|
123
135
|
// the wait ended, so a failed tag watch cleans up rather than leaving debris behind.
|
|
124
|
-
async function
|
|
136
|
+
async function publish_locked(plan: ReleasePlan): Promise<number> {
|
|
125
137
|
const branch_name = branch_name_for(plan.next_version)
|
|
126
138
|
|
|
127
|
-
await
|
|
139
|
+
await clear_the_way(branch_name)
|
|
128
140
|
|
|
129
141
|
const directory = await release_worktree.create(branch_name)
|
|
130
142
|
const previous_cwd = process.cwd()
|
|
@@ -140,6 +152,28 @@ async function publish(plan: ReleasePlan): Promise<number> {
|
|
|
140
152
|
}
|
|
141
153
|
}
|
|
142
154
|
|
|
155
|
+
function release_running_message(target: string): string {
|
|
156
|
+
return `Another \`pnpm josh release\` is running in this repository (lock \`${target}\`); wait for it to finish, then run it again.`
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// **One release at a time per repository, held for the whole run** (joshuafolkken/kit#3058).
|
|
160
|
+
// `clear_leftover` removes an unpushed, commit-less release branch, which is also what a live run
|
|
161
|
+
// looks like while it installs dependencies — so it may only run once no other release is alive. The
|
|
162
|
+
// lock answers that: a run cut off before its `finally` leaves a record whose owner is gone, which
|
|
163
|
+
// `repository_lock` clears on the next claim, while a live owner makes this run refuse at once.
|
|
164
|
+
async function publish(plan: ReleasePlan): Promise<number> {
|
|
165
|
+
const target = repository_lock.lock_path(RELEASE_LOCK_PREFIX)
|
|
166
|
+
const exit_code = await repository_lock.with_lock(
|
|
167
|
+
async () => await publish_locked(plan),
|
|
168
|
+
target,
|
|
169
|
+
RELEASE_LOCK_MAX_WAIT_MS,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
if (exit_code === undefined) throw new Error(release_running_message(target))
|
|
173
|
+
|
|
174
|
+
return exit_code
|
|
175
|
+
}
|
|
176
|
+
|
|
143
177
|
const release_publish = {
|
|
144
178
|
branch_name_for,
|
|
145
179
|
commit_message,
|
|
@@ -150,7 +184,6 @@ const release_publish = {
|
|
|
150
184
|
publish,
|
|
151
185
|
pull_request_body,
|
|
152
186
|
unreachable_remote_message,
|
|
153
|
-
FAILURE_EXIT_CODE,
|
|
154
187
|
SUCCESS_EXIT_CODE,
|
|
155
188
|
}
|
|
156
189
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
import { fileURLToPath } from 'node:url'
|
|
3
|
-
import { git_followup_pending } from '#scripts/
|
|
3
|
+
import { git_followup_pending } from '#scripts/followup/git-followup-pending'
|
|
4
4
|
import { path_decision } from '#scripts/josh/path-decision'
|
|
5
5
|
import { release_plan } from './release-plan'
|
|
6
6
|
|
|
@@ -87,7 +87,6 @@ const release_scope_cli = {
|
|
|
87
87
|
main,
|
|
88
88
|
run,
|
|
89
89
|
JSON_KEY,
|
|
90
|
-
KNOWN_FLAGS,
|
|
91
90
|
NOTHING_PENDING_REASON,
|
|
92
91
|
RELEASE_HINT,
|
|
93
92
|
REQUIRED_SCOPE,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { git_gh_api_path } from '#scripts/
|
|
2
|
-
import { git_gh_exec } from '#scripts/
|
|
1
|
+
import { git_gh_api_path } from '#scripts/gh/git-gh-api-path'
|
|
2
|
+
import { git_gh_exec } from '#scripts/gh/git-gh-exec'
|
|
3
3
|
import { poll, type PollOptions } from '#scripts/lib/poll'
|
|
4
4
|
|
|
5
5
|
// **The release is not finished when the pull request merges — it is finished when the tag exists.**
|
|
@@ -82,12 +82,10 @@ const release_tag = {
|
|
|
82
82
|
attempts_for,
|
|
83
83
|
configured_timeout_seconds,
|
|
84
84
|
format_result,
|
|
85
|
-
tag_exists,
|
|
86
85
|
tag_name,
|
|
87
86
|
wait_for_tag,
|
|
88
87
|
DEFAULT_TIMEOUT_SECONDS,
|
|
89
88
|
TAG_POLL_INTERVAL_MS,
|
|
90
|
-
TIMEOUT_ENV,
|
|
91
89
|
}
|
|
92
90
|
|
|
93
91
|
export { release_tag }
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
2
|
import { git_command } from '#scripts/git/git-command'
|
|
3
|
+
import { git_remote_branch } from '#scripts/git/git-remote-branch'
|
|
3
4
|
import { git_worktree } from '#scripts/git/git-worktree'
|
|
4
5
|
import { lane_install } from '#scripts/lane/lane-install'
|
|
6
|
+
import { lane_leftover } from '#scripts/lane/lane-leftover'
|
|
5
7
|
import { lane_paths } from '#scripts/lane/lane-paths'
|
|
6
8
|
|
|
7
9
|
// The dedicated linked work tree `pnpm josh release` runs inside (joshuafolkken/kit#2411). The whole
|
|
@@ -51,18 +53,111 @@ async function install_or_clean(directory: string, branch_name: string): Promise
|
|
|
51
53
|
// tree on the default branch, so the tree is created directly on the release branch — `git worktree
|
|
52
54
|
// add --no-track -b release/v<version> <dir> origin/<default>`, which `worktree_add` already spells
|
|
53
55
|
// when it is given a start point.
|
|
56
|
+
//
|
|
57
|
+
// **A failed add takes back the branch it made** (joshuafolkken/kit#3058). `git worktree add -b`
|
|
58
|
+
// creates the branch before it looks at the path, so an add refused for a path that already exists
|
|
59
|
+
// still leaves `release/v<version>` behind — and the next run's branch guard then refuses that name
|
|
60
|
+
// as a release already opened. The guard ran before this call and found no such branch, so one
|
|
61
|
+
// present now is this call's own.
|
|
62
|
+
async function add_or_take_back(directory: string, branch_name: string): Promise<void> {
|
|
63
|
+
const default_branch = await git_command.get_default_branch()
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
await git_worktree.worktree_add(directory, branch_name, `origin/${default_branch}`)
|
|
67
|
+
} catch (error) {
|
|
68
|
+
if (await git_command.branch_exists(branch_name)) await git_worktree.branch_delete(branch_name)
|
|
69
|
+
|
|
70
|
+
throw error
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
54
74
|
async function create(branch_name: string): Promise<string> {
|
|
55
75
|
const directory = directory_for(process.cwd())
|
|
56
|
-
const default_branch = await git_command.get_default_branch()
|
|
57
76
|
|
|
58
|
-
await
|
|
77
|
+
await add_or_take_back(directory, branch_name)
|
|
59
78
|
await install_or_clean(directory, branch_name)
|
|
60
79
|
|
|
61
80
|
return directory
|
|
62
81
|
}
|
|
63
82
|
|
|
83
|
+
// **A run that never reached its `finally` leaves its tree and branch behind** (joshuafolkken/kit#3058)
|
|
84
|
+
// — a Ctrl-C, a closed terminal — and every later release then fails on them until a person removes
|
|
85
|
+
// both by hand. They are cleared here only when clearing loses nothing: a release branch origin does
|
|
86
|
+
// not have and that carries no commit beyond `origin/<default>`. Uncommitted edits in the tree are
|
|
87
|
+
// the version bump the next run writes again, so they are not counted as a loss. A branch that was
|
|
88
|
+
// pushed, or that holds a commit, may be a release still in flight, so it is reported and kept. A
|
|
89
|
+
// live run with neither yet is excluded by the caller: `release_publish.publish` holds the release
|
|
90
|
+
// lock, so no other release is alive when this runs.
|
|
91
|
+
const RELEASE_BRANCH_PATTERN = 'release/v*'
|
|
92
|
+
|
|
93
|
+
async function leftover_reason(branch_name: string, base: string): Promise<string | undefined> {
|
|
94
|
+
const answer = await git_remote_branch.ask(branch_name)
|
|
95
|
+
|
|
96
|
+
if (answer !== 'absent') return `origin answers \`${answer}\` for it`
|
|
97
|
+
|
|
98
|
+
const ahead = await git_command.commit_count_beyond(base, branch_name)
|
|
99
|
+
|
|
100
|
+
return ahead === 0 ? undefined : `it holds ${String(ahead)} commit(s) not on \`${base}\``
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function kept_message(directory: string, kept: ReadonlyArray<[string, string]>): string {
|
|
104
|
+
const lines = kept.map(([branch_name, reason]) => `- \`${branch_name}\`: ${reason}`)
|
|
105
|
+
const commands = [
|
|
106
|
+
`git worktree remove --force ${directory}`,
|
|
107
|
+
...kept.map(([branch_name]) => `git branch -D ${branch_name}`),
|
|
108
|
+
].join('; ')
|
|
109
|
+
|
|
110
|
+
return [
|
|
111
|
+
'A previous `pnpm josh release` left release branches that may still be in use, so nothing was removed:',
|
|
112
|
+
...lines,
|
|
113
|
+
`If no release is running, finish or close its pull request, delete the remote branch if it was pushed, then run \`${commands}\` and \`pnpm josh release\` again.`,
|
|
114
|
+
].join('\n')
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async function kept_branches(branches: ReadonlyArray<string>): Promise<Array<[string, string]>> {
|
|
118
|
+
const base = `origin/${await git_command.get_default_branch()}`
|
|
119
|
+
const reasons = await Promise.all(branches.map(async (name) => await leftover_reason(name, base)))
|
|
120
|
+
|
|
121
|
+
return branches.flatMap((name, index) => {
|
|
122
|
+
const reason = reasons[index]
|
|
123
|
+
|
|
124
|
+
return reason === undefined ? [] : [[name, reason] as [string, string]]
|
|
125
|
+
})
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async function is_registered(directory: string): Promise<boolean> {
|
|
129
|
+
const listing = await git_worktree.worktree_list()
|
|
130
|
+
|
|
131
|
+
return listing.split('\n').includes(`worktree ${directory}`)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// The tree goes before the branches, for the reason `remove` gives. A directory git does not register
|
|
135
|
+
// is `lane_leftover.reclaim`'s to remove or refuse — the same test a lane's leftover path gets.
|
|
136
|
+
// Registration is asked before existence: a directory deleted by hand stays registered, and git
|
|
137
|
+
// refuses to delete a branch a registered tree holds until `worktree remove` drops the registration.
|
|
138
|
+
async function remove_leftover_tree(directory: string): Promise<void> {
|
|
139
|
+
if (await is_registered(directory)) await git_worktree.worktree_remove(directory)
|
|
140
|
+
else await lane_leftover.reclaim(directory)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async function clear_leftover(): Promise<void> {
|
|
144
|
+
const directory = directory_for(process.cwd())
|
|
145
|
+
const branches = await git_command.branch_names(RELEASE_BRANCH_PATTERN)
|
|
146
|
+
const kept = await kept_branches(branches)
|
|
147
|
+
|
|
148
|
+
if (kept.length > 0) throw new Error(kept_message(directory, kept))
|
|
149
|
+
|
|
150
|
+
await remove_leftover_tree(directory)
|
|
151
|
+
|
|
152
|
+
for (const branch_name of branches) {
|
|
153
|
+
// eslint-disable-next-line no-await-in-loop -- each `branch -D` takes the same ref lock
|
|
154
|
+
await git_worktree.branch_delete(branch_name)
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
64
158
|
const release_worktree = {
|
|
65
159
|
directory_for,
|
|
160
|
+
clear_leftover,
|
|
66
161
|
create,
|
|
67
162
|
remove,
|
|
68
163
|
RELEASE_WORKTREE_NAME,
|
|
@@ -41,7 +41,7 @@ function format_disabled_detail(repo: string | undefined): ReadonlyArray<string>
|
|
|
41
41
|
` off, so ${WORKFLOW_PATH} fails with`,
|
|
42
42
|
' `Auto-merge is not allowed for this repository` and Dependabot pull requests stay open.',
|
|
43
43
|
` Enable: ${enable_command(repo)}`,
|
|
44
|
-
` ${ORIGIN_ISSUE} distributes the workflow; kit never changes
|
|
44
|
+
` ${ORIGIN_ISSUE} distributes the workflow; kit never changes this setting.`,
|
|
45
45
|
]
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -89,9 +89,6 @@ function format_auto_merge_report(
|
|
|
89
89
|
|
|
90
90
|
const auto_merge_setting_logic = {
|
|
91
91
|
SETTING_LABEL,
|
|
92
|
-
ALLOW_AUTO_MERGE_FIELD,
|
|
93
|
-
WORKFLOW_PATH,
|
|
94
|
-
enable_command,
|
|
95
92
|
classify_auto_merge,
|
|
96
93
|
format_auto_merge_report,
|
|
97
94
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { git_gh_exec } from '#scripts/
|
|
2
|
-
import { REPOSITORY_LABELS, type LabelDefinition } from '#scripts/
|
|
1
|
+
import { git_gh_exec } from '#scripts/gh/git-gh-exec'
|
|
2
|
+
import { REPOSITORY_LABELS, type LabelDefinition } from '#scripts/issue/issue-labels'
|
|
3
3
|
|
|
4
4
|
// Creates the labels kit's workflow and the distributed `pr-classification.yml` rely on, and only
|
|
5
5
|
// those the repository is missing (joshuafolkken/kit#2797). The one place labels are created: `josh
|
|
@@ -86,6 +86,6 @@ function ensure_labels(repo: string | undefined): ReadonlyArray<string> {
|
|
|
86
86
|
return create_missing(missing_labels(existing), repo)
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
const repository_labels = {
|
|
89
|
+
const repository_labels = { ensure_labels }
|
|
90
90
|
|
|
91
91
|
export { repository_labels }
|