@vyuhlabs/dxkit 2.5.1 → 2.6.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/CHANGELOG.md +318 -0
- package/README.md +150 -28
- package/dist/allowlist/categories.d.ts +120 -0
- package/dist/allowlist/categories.d.ts.map +1 -0
- package/dist/allowlist/categories.js +194 -0
- package/dist/allowlist/categories.js.map +1 -0
- package/dist/allowlist/cli.d.ts +95 -0
- package/dist/allowlist/cli.d.ts.map +1 -0
- package/dist/allowlist/cli.js +454 -0
- package/dist/allowlist/cli.js.map +1 -0
- package/dist/allowlist/diff.d.ts +67 -0
- package/dist/allowlist/diff.d.ts.map +1 -0
- package/dist/allowlist/diff.js +147 -0
- package/dist/allowlist/diff.js.map +1 -0
- package/dist/allowlist/file.d.ts +249 -0
- package/dist/allowlist/file.d.ts.map +1 -0
- package/dist/allowlist/file.js +497 -0
- package/dist/allowlist/file.js.map +1 -0
- package/dist/allowlist/gather.d.ts +61 -0
- package/dist/allowlist/gather.d.ts.map +1 -0
- package/dist/allowlist/gather.js +143 -0
- package/dist/allowlist/gather.js.map +1 -0
- package/dist/allowlist/hint.d.ts +80 -0
- package/dist/allowlist/hint.d.ts.map +1 -0
- package/dist/allowlist/hint.js +271 -0
- package/dist/allowlist/hint.js.map +1 -0
- package/dist/allowlist/inline.d.ts +149 -0
- package/dist/allowlist/inline.d.ts.map +1 -0
- package/dist/allowlist/inline.js +306 -0
- package/dist/allowlist/inline.js.map +1 -0
- package/dist/analyzers/tools/tool-registry.d.ts.map +1 -1
- package/dist/analyzers/tools/tool-registry.js +25 -8
- package/dist/analyzers/tools/tool-registry.js.map +1 -1
- package/dist/baseline/baseline-file.d.ts +7 -0
- package/dist/baseline/baseline-file.d.ts.map +1 -1
- package/dist/baseline/baseline-file.js +22 -1
- package/dist/baseline/baseline-file.js.map +1 -1
- package/dist/baseline/check-renderers.d.ts +13 -1
- package/dist/baseline/check-renderers.d.ts.map +1 -1
- package/dist/baseline/check-renderers.js +67 -1
- package/dist/baseline/check-renderers.js.map +1 -1
- package/dist/baseline/check.d.ts +33 -7
- package/dist/baseline/check.d.ts.map +1 -1
- package/dist/baseline/check.js +90 -64
- package/dist/baseline/check.js.map +1 -1
- package/dist/baseline/create.d.ts +35 -7
- package/dist/baseline/create.d.ts.map +1 -1
- package/dist/baseline/create.js +43 -5
- package/dist/baseline/create.js.map +1 -1
- package/dist/baseline/entry-to-located.d.ts +6 -1
- package/dist/baseline/entry-to-located.d.ts.map +1 -1
- package/dist/baseline/entry-to-located.js +20 -2
- package/dist/baseline/entry-to-located.js.map +1 -1
- package/dist/baseline/finding-identity.d.ts.map +1 -1
- package/dist/baseline/finding-identity.js +15 -13
- package/dist/baseline/finding-identity.js.map +1 -1
- package/dist/baseline/modes.d.ts +140 -0
- package/dist/baseline/modes.d.ts.map +1 -0
- package/dist/baseline/modes.js +179 -0
- package/dist/baseline/modes.js.map +1 -0
- package/dist/baseline/policy.d.ts +64 -0
- package/dist/baseline/policy.d.ts.map +1 -1
- package/dist/baseline/policy.js +102 -1
- package/dist/baseline/policy.js.map +1 -1
- package/dist/baseline/producers/health.d.ts +2 -2
- package/dist/baseline/producers/health.d.ts.map +1 -1
- package/dist/baseline/producers/health.js.map +1 -1
- package/dist/baseline/producers/index.d.ts +11 -5
- package/dist/baseline/producers/index.d.ts.map +1 -1
- package/dist/baseline/producers/index.js +12 -9
- package/dist/baseline/producers/index.js.map +1 -1
- package/dist/baseline/producers/quality.d.ts +3 -3
- package/dist/baseline/producers/quality.d.ts.map +1 -1
- package/dist/baseline/producers/quality.js.map +1 -1
- package/dist/baseline/producers/secret-hmac.d.ts +2 -2
- package/dist/baseline/producers/secret-hmac.d.ts.map +1 -1
- package/dist/baseline/producers/secret-hmac.js.map +1 -1
- package/dist/baseline/producers/security.d.ts +2 -2
- package/dist/baseline/producers/security.d.ts.map +1 -1
- package/dist/baseline/producers/security.js.map +1 -1
- package/dist/baseline/producers/stale-allow.d.ts +70 -0
- package/dist/baseline/producers/stale-allow.d.ts.map +1 -0
- package/dist/baseline/producers/stale-allow.js +111 -0
- package/dist/baseline/producers/stale-allow.js.map +1 -0
- package/dist/baseline/producers/tests.d.ts +2 -2
- package/dist/baseline/producers/tests.d.ts.map +1 -1
- package/dist/baseline/producers/tests.js.map +1 -1
- package/dist/baseline/ref-baseline.d.ts +114 -0
- package/dist/baseline/ref-baseline.d.ts.map +1 -0
- package/dist/baseline/ref-baseline.js +260 -0
- package/dist/baseline/ref-baseline.js.map +1 -0
- package/dist/baseline/sanitize.d.ts +80 -0
- package/dist/baseline/sanitize.d.ts.map +1 -0
- package/dist/baseline/sanitize.js +91 -0
- package/dist/baseline/sanitize.js.map +1 -0
- package/dist/baseline/show.d.ts.map +1 -1
- package/dist/baseline/show.js +9 -3
- package/dist/baseline/show.js.map +1 -1
- package/dist/baseline/types.d.ts +73 -26
- package/dist/baseline/types.d.ts.map +1 -1
- package/dist/baseline/types.js +7 -1
- package/dist/baseline/types.js.map +1 -1
- package/dist/baseline/visibility.d.ts +61 -0
- package/dist/baseline/visibility.d.ts.map +1 -0
- package/dist/baseline/visibility.js +121 -0
- package/dist/baseline/visibility.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +154 -13
- package/dist/cli.js.map +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +0 -10
- package/dist/constants.js.map +1 -1
- package/dist/detect.d.ts.map +1 -1
- package/dist/detect.js +0 -15
- package/dist/detect.js.map +1 -1
- package/dist/doctor.d.ts +78 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +590 -101
- package/dist/doctor.js.map +1 -1
- package/dist/generator.d.ts.map +1 -1
- package/dist/generator.js +15 -0
- package/dist/generator.js.map +1 -1
- package/dist/issue-cli.d.ts +62 -0
- package/dist/issue-cli.d.ts.map +1 -0
- package/dist/issue-cli.js +252 -0
- package/dist/issue-cli.js.map +1 -0
- package/dist/languages/csharp.d.ts.map +1 -1
- package/dist/languages/csharp.js +2 -0
- package/dist/languages/csharp.js.map +1 -1
- package/dist/languages/go.d.ts.map +1 -1
- package/dist/languages/go.js +2 -0
- package/dist/languages/go.js.map +1 -1
- package/dist/languages/index.d.ts +25 -0
- package/dist/languages/index.d.ts.map +1 -1
- package/dist/languages/index.js +44 -0
- package/dist/languages/index.js.map +1 -1
- package/dist/languages/java.d.ts.map +1 -1
- package/dist/languages/java.js +2 -0
- package/dist/languages/java.js.map +1 -1
- package/dist/languages/kotlin.d.ts.map +1 -1
- package/dist/languages/kotlin.js +2 -0
- package/dist/languages/kotlin.js.map +1 -1
- package/dist/languages/python.d.ts.map +1 -1
- package/dist/languages/python.js +11 -1
- package/dist/languages/python.js.map +1 -1
- package/dist/languages/ruby.d.ts.map +1 -1
- package/dist/languages/ruby.js +2 -0
- package/dist/languages/ruby.js.map +1 -1
- package/dist/languages/rust.d.ts.map +1 -1
- package/dist/languages/rust.js +2 -0
- package/dist/languages/rust.js.map +1 -1
- package/dist/languages/types.d.ts +45 -0
- package/dist/languages/types.d.ts.map +1 -1
- package/dist/languages/typescript.d.ts.map +1 -1
- package/dist/languages/typescript.js +2 -0
- package/dist/languages/typescript.js.map +1 -1
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +0 -5
- package/dist/prompts.js.map +1 -1
- package/dist/setup-branch-protection.d.ts +34 -0
- package/dist/setup-branch-protection.d.ts.map +1 -0
- package/dist/setup-branch-protection.js +190 -0
- package/dist/setup-branch-protection.js.map +1 -0
- package/dist/setup-gh.d.ts +75 -0
- package/dist/setup-gh.d.ts.map +1 -0
- package/dist/setup-gh.js +213 -0
- package/dist/setup-gh.js.map +1 -0
- package/dist/setup-prebuild.d.ts +34 -0
- package/dist/setup-prebuild.d.ts.map +1 -0
- package/dist/setup-prebuild.js +181 -0
- package/dist/setup-prebuild.js.map +1 -0
- package/dist/ship-installers.d.ts.map +1 -1
- package/dist/ship-installers.js +19 -4
- package/dist/ship-installers.js.map +1 -1
- package/dist/types.d.ts +24 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/update.d.ts +41 -0
- package/dist/update.d.ts.map +1 -1
- package/dist/update.js +154 -15
- package/dist/update.js.map +1 -1
- package/dist/upgrade.d.ts +88 -0
- package/dist/upgrade.d.ts.map +1 -0
- package/dist/upgrade.js +324 -0
- package/dist/upgrade.js.map +1 -0
- package/package.json +1 -1
- package/templates/.claude/skills/dxkit-action/SKILL.md +111 -17
- package/templates/.claude/skills/dxkit-config/SKILL.md +7 -7
- package/templates/.claude/skills/dxkit-fix/SKILL.md +165 -0
- package/templates/.claude/skills/dxkit-hooks/SKILL.md +8 -8
- package/templates/.claude/skills/dxkit-init/SKILL.md +3 -3
- package/templates/.claude/skills/dxkit-learn/SKILL.md +9 -9
- package/templates/.claude/skills/dxkit-onboard/SKILL.md +274 -0
- package/templates/.claude/skills/dxkit-reports/SKILL.md +18 -18
- package/templates/.claude/skills/dxkit-update/SKILL.md +164 -0
- package/templates/.devcontainer/devcontainer.json +6 -15
- package/templates/.devcontainer/post-create.sh +19 -4
- package/dist/baseline/producers/licenses.d.ts +0 -23
- package/dist/baseline/producers/licenses.d.ts.map +0 -1
- package/dist/baseline/producers/licenses.js +0 -46
- package/dist/baseline/producers/licenses.js.map +0 -1
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* `vyuh-dxkit setup-branch-protection` — configures branch protection
|
|
4
|
+
* on the repo's default branch with dxkit's guardrail workflow listed
|
|
5
|
+
* as a required status check. Without this step, the dxkit-guardrails
|
|
6
|
+
* workflow we install only runs informationally — PRs can merge even
|
|
7
|
+
* if the guardrail fails. With it, merges are blocked on guardrail
|
|
8
|
+
* failures.
|
|
9
|
+
*
|
|
10
|
+
* Wraps `gh api -X PUT repos/{owner}/{repo}/branches/{branch}/protection`
|
|
11
|
+
* with a JSON payload that:
|
|
12
|
+
* 1. Adds `dxkit-guardrails` to required status checks
|
|
13
|
+
* 2. Preserves any other required checks already configured
|
|
14
|
+
* (idempotent merge — don't clobber customer policy)
|
|
15
|
+
* 3. Doesn't force a review-count policy by default (set --require-reviews=N if wanted)
|
|
16
|
+
*
|
|
17
|
+
* Edge cases handled:
|
|
18
|
+
* - gh CLI missing → preflight fails with clear install instructions
|
|
19
|
+
* - No github.com remote → resolveOwnerRepo throws GhError with suggestion
|
|
20
|
+
* - Customer not admin (HTTP 403) → ghApi throws with admin-asks suggestion
|
|
21
|
+
* - Workflow file missing → warn before applying (the protection rule
|
|
22
|
+
* would otherwise block ALL PRs until the workflow exists)
|
|
23
|
+
* - Existing protection rule with different required checks → merge
|
|
24
|
+
* dxkit-guardrails into the list instead of replacing
|
|
25
|
+
*/
|
|
26
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
27
|
+
if (k2 === undefined) k2 = k;
|
|
28
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
29
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
30
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
31
|
+
}
|
|
32
|
+
Object.defineProperty(o, k2, desc);
|
|
33
|
+
}) : (function(o, m, k, k2) {
|
|
34
|
+
if (k2 === undefined) k2 = k;
|
|
35
|
+
o[k2] = m[k];
|
|
36
|
+
}));
|
|
37
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
38
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
39
|
+
}) : function(o, v) {
|
|
40
|
+
o["default"] = v;
|
|
41
|
+
});
|
|
42
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
43
|
+
var ownKeys = function(o) {
|
|
44
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
45
|
+
var ar = [];
|
|
46
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
47
|
+
return ar;
|
|
48
|
+
};
|
|
49
|
+
return ownKeys(o);
|
|
50
|
+
};
|
|
51
|
+
return function (mod) {
|
|
52
|
+
if (mod && mod.__esModule) return mod;
|
|
53
|
+
var result = {};
|
|
54
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
55
|
+
__setModuleDefault(result, mod);
|
|
56
|
+
return result;
|
|
57
|
+
};
|
|
58
|
+
})();
|
|
59
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
60
|
+
exports.runSetupBranchProtection = runSetupBranchProtection;
|
|
61
|
+
const fs = __importStar(require("fs"));
|
|
62
|
+
const path = __importStar(require("path"));
|
|
63
|
+
const logger = __importStar(require("./logger"));
|
|
64
|
+
const setup_gh_1 = require("./setup-gh");
|
|
65
|
+
const REQUIRED_CHECK = 'dxkit-guardrails';
|
|
66
|
+
function readExistingProtection(cwd, owner, repo, branch) {
|
|
67
|
+
try {
|
|
68
|
+
return (0, setup_gh_1.ghApi)(`repos/${owner}/${repo}/branches/${branch}/protection`, {
|
|
69
|
+
cwd,
|
|
70
|
+
method: 'GET',
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
if (e instanceof setup_gh_1.GhError && e.httpStatus === 404) {
|
|
75
|
+
// No protection rule exists yet — that's expected for the
|
|
76
|
+
// common case where we're the first to configure one.
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
throw e;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Build the protection payload by merging dxkit-guardrails into any
|
|
84
|
+
* existing required-checks list. Preserves customer-configured
|
|
85
|
+
* required checks, review counts, and admin-enforcement settings.
|
|
86
|
+
*/
|
|
87
|
+
function buildPayload(existing, opts) {
|
|
88
|
+
// Existing required checks — preserve, then ensure dxkit-guardrails is in the set.
|
|
89
|
+
const existingChecks = existing?.required_status_checks?.contexts ?? [];
|
|
90
|
+
const mergedChecks = opts.force
|
|
91
|
+
? [REQUIRED_CHECK]
|
|
92
|
+
: [...new Set([...existingChecks, REQUIRED_CHECK])];
|
|
93
|
+
// Reviews policy — only override when the customer passed --require-reviews.
|
|
94
|
+
// Without it, preserve whatever was there (or set null if no prior rule).
|
|
95
|
+
let reviews = null;
|
|
96
|
+
if (opts.requireReviews !== undefined && opts.requireReviews > 0) {
|
|
97
|
+
reviews = {
|
|
98
|
+
dismiss_stale_reviews: false,
|
|
99
|
+
require_code_owner_reviews: false,
|
|
100
|
+
required_approving_review_count: opts.requireReviews,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
else if (existing?.required_pull_request_reviews) {
|
|
104
|
+
reviews = existing.required_pull_request_reviews;
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
required_status_checks: { strict: false, contexts: mergedChecks },
|
|
108
|
+
enforce_admins: existing?.enforce_admins ?? false,
|
|
109
|
+
required_pull_request_reviews: reviews,
|
|
110
|
+
restrictions: null, // user/team push restrictions — out of scope here
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function checkWorkflowFile(cwd) {
|
|
114
|
+
const wfPath = path.join(cwd, '.github', 'workflows', 'dxkit-guardrails.yml');
|
|
115
|
+
return fs.existsSync(wfPath);
|
|
116
|
+
}
|
|
117
|
+
async function runSetupBranchProtection(cwd, opts = {}) {
|
|
118
|
+
logger.header('vyuh-dxkit setup-branch-protection');
|
|
119
|
+
if (!(0, setup_gh_1.preflightGhCli)('setup-branch-protection')) {
|
|
120
|
+
process.exitCode = 1;
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
let ownerRepo;
|
|
124
|
+
try {
|
|
125
|
+
ownerRepo = (0, setup_gh_1.resolveOwnerRepo)(cwd);
|
|
126
|
+
}
|
|
127
|
+
catch (e) {
|
|
128
|
+
if (e instanceof setup_gh_1.GhError) {
|
|
129
|
+
process.exitCode = (0, setup_gh_1.renderGhError)(e, 'Resolve repo');
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
throw e;
|
|
133
|
+
}
|
|
134
|
+
const { owner, repo } = ownerRepo;
|
|
135
|
+
const branch = opts.branch ?? (0, setup_gh_1.resolveDefaultBranch)(cwd);
|
|
136
|
+
// Warn if the workflow file isn't present — protection-by-name would
|
|
137
|
+
// otherwise block ALL PRs until the workflow is added.
|
|
138
|
+
if (!checkWorkflowFile(cwd)) {
|
|
139
|
+
logger.warn('No .github/workflows/dxkit-guardrails.yml found. Applying branch protection ' +
|
|
140
|
+
'now would block every PR until that workflow exists.');
|
|
141
|
+
logger.dim(' → Run `vyuh-dxkit init --with-ci --yes` first to scaffold the workflow.');
|
|
142
|
+
process.exitCode = 1;
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
logger.info(`Resolving existing protection on ${owner}/${repo}#${branch}...`);
|
|
146
|
+
let existing;
|
|
147
|
+
try {
|
|
148
|
+
existing = readExistingProtection(cwd, owner, repo, branch);
|
|
149
|
+
}
|
|
150
|
+
catch (e) {
|
|
151
|
+
if (e instanceof setup_gh_1.GhError) {
|
|
152
|
+
process.exitCode = (0, setup_gh_1.renderGhError)(e, 'Read existing protection');
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
throw e;
|
|
156
|
+
}
|
|
157
|
+
if (existing) {
|
|
158
|
+
logger.info(` → Found ${existing.required_status_checks?.contexts.length ?? 0} existing required check(s); ` +
|
|
159
|
+
`dxkit-guardrails ${existing.required_status_checks?.contexts.includes(REQUIRED_CHECK)
|
|
160
|
+
? 'already in list'
|
|
161
|
+
: 'will be merged in'}.`);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
logger.info(' → No existing protection rule; creating one with dxkit-guardrails as required.');
|
|
165
|
+
}
|
|
166
|
+
const payload = buildPayload(existing, opts);
|
|
167
|
+
logger.info(`Applying protection: required checks = [${payload.required_status_checks?.contexts.join(', ')}]; ` +
|
|
168
|
+
`reviews required = ${payload.required_pull_request_reviews?.required_approving_review_count ?? 0}.`);
|
|
169
|
+
try {
|
|
170
|
+
(0, setup_gh_1.ghApi)(`repos/${owner}/${repo}/branches/${branch}/protection`, {
|
|
171
|
+
cwd,
|
|
172
|
+
method: 'PUT',
|
|
173
|
+
inputJson: JSON.stringify(payload),
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
catch (e) {
|
|
177
|
+
if (e instanceof setup_gh_1.GhError) {
|
|
178
|
+
process.exitCode = (0, setup_gh_1.renderGhError)(e, 'Apply protection');
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
throw e;
|
|
182
|
+
}
|
|
183
|
+
console.log(''); // slop-ok
|
|
184
|
+
logger.success(`Branch protection applied to ${owner}/${repo}#${branch}.`);
|
|
185
|
+
logger.dim(` → Verify: https://github.com/${owner}/${repo}/settings/branches`);
|
|
186
|
+
if (!payload.required_pull_request_reviews) {
|
|
187
|
+
logger.dim(' → Review-count policy NOT changed (pass --require-reviews=N to require reviews).');
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=setup-branch-protection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-branch-protection.js","sourceRoot":"","sources":["../src/setup-branch-protection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for the `setup-branch-protection` and `setup-prebuild`
|
|
3
|
+
* CLI subcommands. Both wrap GitHub API calls behind `gh api` for the
|
|
4
|
+
* common path, with consistent detection / error messaging / repo
|
|
5
|
+
* resolution. Co-locating the shared surface keeps the two subcommand
|
|
6
|
+
* modules focused on payload construction.
|
|
7
|
+
*/
|
|
8
|
+
export interface OwnerRepo {
|
|
9
|
+
owner: string;
|
|
10
|
+
repo: string;
|
|
11
|
+
}
|
|
12
|
+
export declare class GhError extends Error {
|
|
13
|
+
readonly httpStatus?: number;
|
|
14
|
+
readonly suggestion?: string;
|
|
15
|
+
constructor(message: string, opts?: {
|
|
16
|
+
httpStatus?: number;
|
|
17
|
+
suggestion?: string;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Returns true if `gh` is on PATH and authenticated.
|
|
22
|
+
*
|
|
23
|
+
* Both setup-branch-protection and setup-prebuild require the gh CLI
|
|
24
|
+
* (we don't ship an octokit-based fallback in 2.5.2 — keeps the
|
|
25
|
+
* dependency surface narrow). Future octokit fallback would slot in
|
|
26
|
+
* here without changing callers.
|
|
27
|
+
*/
|
|
28
|
+
export declare function ghCliAvailable(): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Resolve the owner+repo of the current git working tree using
|
|
31
|
+
* `gh repo view --json owner,name`. Requires gh to be authenticated
|
|
32
|
+
* AND the repo to have a github.com remote configured (gh respects
|
|
33
|
+
* the same git-remote conventions).
|
|
34
|
+
*
|
|
35
|
+
* Throws GhError with actionable suggestion on every failure path so
|
|
36
|
+
* the callers can render a clean error to the customer.
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveOwnerRepo(cwd: string): OwnerRepo;
|
|
39
|
+
/**
|
|
40
|
+
* Resolve the repo's default branch via `gh repo view --json
|
|
41
|
+
* defaultBranchRef`. Used as the default `--branch` when the customer
|
|
42
|
+
* doesn't pass one explicitly — most repos use `main` but legacy
|
|
43
|
+
* repos may still default to `master` etc.
|
|
44
|
+
*/
|
|
45
|
+
export declare function resolveDefaultBranch(cwd: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Call `gh api` with the given args and return the parsed JSON body.
|
|
48
|
+
* Throws GhError with the parsed HTTP status when the call fails so
|
|
49
|
+
* callers can branch on 403 / 404 / 422 specifically.
|
|
50
|
+
*
|
|
51
|
+
* `args` should NOT include the `-X METHOD` flag — pass it via
|
|
52
|
+
* `opts.method`. The endpoint is added at the end.
|
|
53
|
+
*/
|
|
54
|
+
export declare function ghApi(endpoint: string, opts: {
|
|
55
|
+
cwd: string;
|
|
56
|
+
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
57
|
+
inputJson?: string;
|
|
58
|
+
extraArgs?: string[];
|
|
59
|
+
}): unknown;
|
|
60
|
+
/**
|
|
61
|
+
* Render a GhError to the customer. Returns the exit code the CLI
|
|
62
|
+
* should use (always 1 for now, but kept as a separate return for
|
|
63
|
+
* future "warn but don't fail" cases).
|
|
64
|
+
*/
|
|
65
|
+
export declare function renderGhError(err: GhError, context: string): number;
|
|
66
|
+
/**
|
|
67
|
+
* Pre-flight check shared by both setup commands. Verifies gh CLI is
|
|
68
|
+
* available + authenticated. Renders the manual-fallback instructions
|
|
69
|
+
* if gh is missing rather than throwing — keeps the customer's
|
|
70
|
+
* troubleshooting path consistent.
|
|
71
|
+
*
|
|
72
|
+
* Returns true if pre-flight passes; false (with rendered error) if not.
|
|
73
|
+
*/
|
|
74
|
+
export declare function preflightGhCli(commandName: string): boolean;
|
|
75
|
+
//# sourceMappingURL=setup-gh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-gh.d.ts","sourceRoot":"","sources":["../src/setup-gh.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,OAAQ,SAAQ,KAAK;IAChC,SAAgB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpC,SAAgB,UAAU,CAAC,EAAE,MAAM,CAAC;gBAExB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;CAMjF;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAQxC;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CA4BvD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAaxD;AAED;;;;;;;GAOG;AACH,wBAAgB,KAAK,CACnB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE;IACJ,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,GACA,OAAO,CAmCT;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAInE;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAM3D"}
|
package/dist/setup-gh.js
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared helpers for the `setup-branch-protection` and `setup-prebuild`
|
|
4
|
+
* CLI subcommands. Both wrap GitHub API calls behind `gh api` for the
|
|
5
|
+
* common path, with consistent detection / error messaging / repo
|
|
6
|
+
* resolution. Co-locating the shared surface keeps the two subcommand
|
|
7
|
+
* modules focused on payload construction.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.GhError = void 0;
|
|
44
|
+
exports.ghCliAvailable = ghCliAvailable;
|
|
45
|
+
exports.resolveOwnerRepo = resolveOwnerRepo;
|
|
46
|
+
exports.resolveDefaultBranch = resolveDefaultBranch;
|
|
47
|
+
exports.ghApi = ghApi;
|
|
48
|
+
exports.renderGhError = renderGhError;
|
|
49
|
+
exports.preflightGhCli = preflightGhCli;
|
|
50
|
+
const child_process_1 = require("child_process");
|
|
51
|
+
const logger = __importStar(require("./logger"));
|
|
52
|
+
class GhError extends Error {
|
|
53
|
+
httpStatus;
|
|
54
|
+
suggestion;
|
|
55
|
+
constructor(message, opts) {
|
|
56
|
+
super(message);
|
|
57
|
+
this.name = 'GhError';
|
|
58
|
+
this.httpStatus = opts?.httpStatus;
|
|
59
|
+
this.suggestion = opts?.suggestion;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.GhError = GhError;
|
|
63
|
+
/**
|
|
64
|
+
* Returns true if `gh` is on PATH and authenticated.
|
|
65
|
+
*
|
|
66
|
+
* Both setup-branch-protection and setup-prebuild require the gh CLI
|
|
67
|
+
* (we don't ship an octokit-based fallback in 2.5.2 — keeps the
|
|
68
|
+
* dependency surface narrow). Future octokit fallback would slot in
|
|
69
|
+
* here without changing callers.
|
|
70
|
+
*/
|
|
71
|
+
function ghCliAvailable() {
|
|
72
|
+
try {
|
|
73
|
+
(0, child_process_1.execSync)('gh --version', { stdio: 'pipe' });
|
|
74
|
+
(0, child_process_1.execSync)('gh auth status', { stdio: 'pipe' });
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Resolve the owner+repo of the current git working tree using
|
|
83
|
+
* `gh repo view --json owner,name`. Requires gh to be authenticated
|
|
84
|
+
* AND the repo to have a github.com remote configured (gh respects
|
|
85
|
+
* the same git-remote conventions).
|
|
86
|
+
*
|
|
87
|
+
* Throws GhError with actionable suggestion on every failure path so
|
|
88
|
+
* the callers can render a clean error to the customer.
|
|
89
|
+
*/
|
|
90
|
+
function resolveOwnerRepo(cwd) {
|
|
91
|
+
try {
|
|
92
|
+
const out = (0, child_process_1.execSync)('gh repo view --json owner,name', {
|
|
93
|
+
cwd,
|
|
94
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
95
|
+
encoding: 'utf-8',
|
|
96
|
+
});
|
|
97
|
+
const parsed = JSON.parse(out);
|
|
98
|
+
if (!parsed.owner?.login || !parsed.name) {
|
|
99
|
+
throw new GhError('gh repo view returned an unexpected payload — re-run `gh auth login`.');
|
|
100
|
+
}
|
|
101
|
+
return { owner: parsed.owner.login, repo: parsed.name };
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
if (e instanceof GhError)
|
|
105
|
+
throw e;
|
|
106
|
+
const msg = e.stderr?.toString() ?? e.message;
|
|
107
|
+
if (msg.includes('not a git repository') || msg.includes('no remote')) {
|
|
108
|
+
throw new GhError('Repo has no github.com remote configured. Add the remote and push first.', {
|
|
109
|
+
suggestion: 'git remote add origin git@github.com:OWNER/REPO.git && git push -u origin main',
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
throw new GhError(`Could not resolve repo via gh: ${msg.trim().split('\n')[0]}`, {
|
|
113
|
+
suggestion: 'Run `gh auth login` and confirm `gh repo view` works.',
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Resolve the repo's default branch via `gh repo view --json
|
|
119
|
+
* defaultBranchRef`. Used as the default `--branch` when the customer
|
|
120
|
+
* doesn't pass one explicitly — most repos use `main` but legacy
|
|
121
|
+
* repos may still default to `master` etc.
|
|
122
|
+
*/
|
|
123
|
+
function resolveDefaultBranch(cwd) {
|
|
124
|
+
try {
|
|
125
|
+
const out = (0, child_process_1.execSync)('gh repo view --json defaultBranchRef', {
|
|
126
|
+
cwd,
|
|
127
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
128
|
+
encoding: 'utf-8',
|
|
129
|
+
});
|
|
130
|
+
const parsed = JSON.parse(out);
|
|
131
|
+
if (parsed.defaultBranchRef?.name)
|
|
132
|
+
return parsed.defaultBranchRef.name;
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
/* fall through to fallback */
|
|
136
|
+
}
|
|
137
|
+
return 'main';
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Call `gh api` with the given args and return the parsed JSON body.
|
|
141
|
+
* Throws GhError with the parsed HTTP status when the call fails so
|
|
142
|
+
* callers can branch on 403 / 404 / 422 specifically.
|
|
143
|
+
*
|
|
144
|
+
* `args` should NOT include the `-X METHOD` flag — pass it via
|
|
145
|
+
* `opts.method`. The endpoint is added at the end.
|
|
146
|
+
*/
|
|
147
|
+
function ghApi(endpoint, opts) {
|
|
148
|
+
const args = ['api'];
|
|
149
|
+
if (opts.method && opts.method !== 'GET')
|
|
150
|
+
args.push('-X', opts.method);
|
|
151
|
+
if (opts.inputJson)
|
|
152
|
+
args.push('--input', '-');
|
|
153
|
+
if (opts.extraArgs)
|
|
154
|
+
args.push(...opts.extraArgs);
|
|
155
|
+
args.push(endpoint);
|
|
156
|
+
try {
|
|
157
|
+
const out = (0, child_process_1.execSync)(`gh ${args.map((a) => JSON.stringify(a)).join(' ')}`, {
|
|
158
|
+
cwd: opts.cwd,
|
|
159
|
+
stdio: opts.inputJson ? ['pipe', 'pipe', 'pipe'] : ['ignore', 'pipe', 'pipe'],
|
|
160
|
+
encoding: 'utf-8',
|
|
161
|
+
input: opts.inputJson,
|
|
162
|
+
});
|
|
163
|
+
return out.trim() ? JSON.parse(out) : null;
|
|
164
|
+
}
|
|
165
|
+
catch (e) {
|
|
166
|
+
const stderr = (e.stderr?.toString() ?? '').trim();
|
|
167
|
+
const statusMatch = stderr.match(/HTTP (\d+):/);
|
|
168
|
+
const httpStatus = statusMatch ? parseInt(statusMatch[1], 10) : undefined;
|
|
169
|
+
if (httpStatus === 403) {
|
|
170
|
+
throw new GhError('Permission denied — you need admin rights on the repo.', {
|
|
171
|
+
httpStatus,
|
|
172
|
+
suggestion: 'Ask a repo admin to run this command, or configure manually in repo Settings.',
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
if (httpStatus === 404) {
|
|
176
|
+
throw new GhError('Endpoint not found — repo may not exist or you may lack access.', {
|
|
177
|
+
httpStatus,
|
|
178
|
+
suggestion: 'Verify the repo via `gh repo view`.',
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
throw new GhError(`gh api failed (HTTP ${httpStatus ?? '?'}): ${stderr.split('\n')[0]}`, {
|
|
182
|
+
httpStatus,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Render a GhError to the customer. Returns the exit code the CLI
|
|
188
|
+
* should use (always 1 for now, but kept as a separate return for
|
|
189
|
+
* future "warn but don't fail" cases).
|
|
190
|
+
*/
|
|
191
|
+
function renderGhError(err, context) {
|
|
192
|
+
logger.fail(`${context}: ${err.message}`);
|
|
193
|
+
if (err.suggestion)
|
|
194
|
+
logger.dim(` → ${err.suggestion}`);
|
|
195
|
+
return 1;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Pre-flight check shared by both setup commands. Verifies gh CLI is
|
|
199
|
+
* available + authenticated. Renders the manual-fallback instructions
|
|
200
|
+
* if gh is missing rather than throwing — keeps the customer's
|
|
201
|
+
* troubleshooting path consistent.
|
|
202
|
+
*
|
|
203
|
+
* Returns true if pre-flight passes; false (with rendered error) if not.
|
|
204
|
+
*/
|
|
205
|
+
function preflightGhCli(commandName) {
|
|
206
|
+
if (ghCliAvailable())
|
|
207
|
+
return true;
|
|
208
|
+
logger.fail(`${commandName}: gh CLI not available or not authenticated.`);
|
|
209
|
+
logger.dim(' → Install gh: https://cli.github.com');
|
|
210
|
+
logger.dim(' → Authenticate: `gh auth login`');
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=setup-gh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-gh.js","sourceRoot":"","sources":["../src/setup-gh.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `vyuh-dxkit setup-prebuild` — configures GitHub Codespaces prebuilds
|
|
3
|
+
* for the repo, so fresh Codespaces start from a prebuilt image
|
|
4
|
+
* instead of re-running the full devcontainer build.
|
|
5
|
+
*
|
|
6
|
+
* Math: dxkit's polyglot devcontainer takes ~7 min cold-start (post per-
|
|
7
|
+
* stack feature work in Sprint 1). Prebuilds drop this to ~30s by
|
|
8
|
+
* maintaining the built image in GitHub's image cache. Storage cost
|
|
9
|
+
* ~$3-5/month per region; for a 20-dev team averaging 5 fresh
|
|
10
|
+
* Codespaces/week, the wall-clock savings dwarf the cost by 2-3 orders
|
|
11
|
+
* of magnitude.
|
|
12
|
+
*
|
|
13
|
+
* Wraps `gh api -X POST repos/{owner}/{repo}/codespaces/prebuilds` with
|
|
14
|
+
* a JSON payload defining branch + region + retention. Edge cases:
|
|
15
|
+
* - gh CLI missing → preflight fails
|
|
16
|
+
* - No .devcontainer/ → fail with "run init --with-devcontainer first"
|
|
17
|
+
* - Org Codespaces disabled → HTTP 403 / 422 with org-admin guidance
|
|
18
|
+
* - Existing prebuild config for the same branch → skip with notice
|
|
19
|
+
* (idempotency; avoids accidental clobber of customer-chosen regions)
|
|
20
|
+
*/
|
|
21
|
+
export interface SetupPrebuildOpts {
|
|
22
|
+
/** Branch to prebuild. Defaults to the repo's default branch. */
|
|
23
|
+
branch?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Region(s) to prebuild in. If undefined, GitHub picks a reasonable
|
|
26
|
+
* default (typically the customer's nearest region based on their
|
|
27
|
+
* Codespaces preferences). Comma-separated list when multiple.
|
|
28
|
+
*/
|
|
29
|
+
regions?: string;
|
|
30
|
+
/** Force re-create even if a prebuild config exists for the branch. */
|
|
31
|
+
force?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export declare function runSetupPrebuild(cwd: string, opts?: SetupPrebuildOpts): Promise<void>;
|
|
34
|
+
//# sourceMappingURL=setup-prebuild.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-prebuild.d.ts","sourceRoot":"","sources":["../src/setup-prebuild.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAcH,MAAM,WAAW,iBAAiB;IAChC,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAuCD,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoH/F"}
|