@xcelera/cli 1.2.0 → 1.2.2

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.
@@ -68,43 +68,3 @@ jobs:
68
68
  - name: Print Output
69
69
  id: output
70
70
  run: echo "${{ steps.test-action.outputs.status }}"
71
-
72
- - name: Release
73
- env:
74
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
75
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
76
- run: npx semantic-release
77
-
78
- release:
79
- name: Release
80
- runs-on: ubuntu-latest
81
- permissions:
82
- contents: write # to be able to publish a GitHub release
83
- issues: write # to be able to comment on released issues
84
- pull-requests: write # to be able to comment on released pull requests
85
- id-token: write # to enable use of OIDC for npm provenance
86
-
87
- steps:
88
- - name: Checkout
89
- uses: actions/checkout@v4
90
- with:
91
- fetch-depth: 0
92
-
93
- - name: Setup Node.js
94
- uses: actions/setup-node@v4
95
- with:
96
- node-version: 'lts/*'
97
-
98
- - name: Install dependencies
99
- run: npm clean-install
100
-
101
- - name:
102
- Verify the integrity of provenance attestations and registry
103
- signatures for installed dependencies
104
- run: npm audit signatures
105
-
106
- - name: Release
107
- env:
108
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
109
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
110
- run: npx semantic-release
@@ -0,0 +1,56 @@
1
+ name: Release
2
+
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - main
7
+ push:
8
+ branches:
9
+ - main
10
+ workflow_run:
11
+ workflows: [Continuous Integration]
12
+ types: [completed]
13
+
14
+ permissions:
15
+ contents: read
16
+
17
+ jobs:
18
+ release:
19
+ name: Release
20
+ if: ${{ github.event.workflow_run.conclusion == 'success' }}
21
+ runs-on: ubuntu-latest
22
+ permissions:
23
+ contents: write # to be able to publish a GitHub release
24
+ issues: write # to be able to comment on released issues
25
+ pull-requests: write # to be able to comment on released pull requests
26
+ id-token: write # to enable use of OIDC for npm provenance
27
+
28
+ steps:
29
+ - name: Checkout
30
+ uses: actions/checkout@v4
31
+ with:
32
+ fetch-depth: 0
33
+
34
+ - name: Setup Node.js
35
+ id: setup-node
36
+ uses: actions/setup-node@v4
37
+ with:
38
+ node-version-file: .node-version
39
+ cache: npm
40
+
41
+ - name: Install dependencies
42
+ run: npm clean-install
43
+
44
+ - name:
45
+ Verify the integrity of provenance attestations and registry
46
+ signatures for installed dependencies
47
+ run: npm audit signatures
48
+
49
+ - name: package
50
+ run: npm run package
51
+
52
+ - name: Release
53
+ env:
54
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
55
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
56
+ run: npx semantic-release
package/dist/cli.js ADDED
@@ -0,0 +1,307 @@
1
+ #!/usr/bin/env node
2
+ import { parseArgs } from 'node:util';
3
+ import { execSync } from 'node:child_process';
4
+ import require$$0 from 'url';
5
+
6
+ async function requestAudit(url, token, github) {
7
+ const apiUrl = `${getApiBaseUrl()}/api/v1/audit`;
8
+ const response = await fetch(apiUrl, {
9
+ method: 'POST',
10
+ headers: {
11
+ 'Content-Type': 'application/json',
12
+ Authorization: `Bearer ${token}`
13
+ },
14
+ body: JSON.stringify({
15
+ url,
16
+ github
17
+ })
18
+ });
19
+ if (!response.ok) {
20
+ const errorText = await response.text();
21
+ throw new Error(`API request failed: ${response.status} ${response.statusText} - ${errorText}`);
22
+ }
23
+ const data = await response.json();
24
+ return data;
25
+ }
26
+ function getApiBaseUrl() {
27
+ if (process.env.NODE_ENV === 'development' ||
28
+ process.env.GITHUB_ACTIONS !== 'true') {
29
+ return 'http://localhost:3000';
30
+ }
31
+ return 'https://xcelera.dev';
32
+ }
33
+
34
+ function getDefaultExportFromCjs (x) {
35
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
36
+ }
37
+
38
+ /*!
39
+ * parse-github-url <https://github.com/jonschlinkert/parse-github-url>
40
+ *
41
+ * Copyright (c) 2015-2017, Jon Schlinkert.
42
+ * Released under the MIT License.
43
+ */
44
+
45
+ var parseGithubUrl$1;
46
+ var hasRequiredParseGithubUrl;
47
+
48
+ function requireParseGithubUrl () {
49
+ if (hasRequiredParseGithubUrl) return parseGithubUrl$1;
50
+ hasRequiredParseGithubUrl = 1;
51
+
52
+ var url = require$$0;
53
+ var cache = { __proto__: null };
54
+
55
+ function isChecksum(str) {
56
+ return (/^[a-f0-9]{40}$/i).test(str);
57
+ }
58
+
59
+ function getBranch(str, obj) {
60
+ var segs = str.split('#');
61
+ var branch;
62
+ if (segs.length > 1) {
63
+ branch = segs[segs.length - 1];
64
+ }
65
+ if (!branch && obj.hash && obj.hash.charAt(0) === '#') {
66
+ branch = obj.hash.slice(1);
67
+ }
68
+ return branch || 'master';
69
+ }
70
+
71
+ function trimSlash(path) {
72
+ return path.charAt(0) === '/' ? path.slice(1) : path;
73
+ }
74
+
75
+ function name(str) {
76
+ return str ? str.replace(/\.git$/, '') : null;
77
+ }
78
+
79
+ function owner(str) {
80
+ if (!str) {
81
+ return null;
82
+ }
83
+ var idx = str.indexOf(':');
84
+ if (idx > -1) {
85
+ return str.slice(idx + 1);
86
+ }
87
+ return str;
88
+ }
89
+
90
+ function parse(str) {
91
+ if (typeof str !== 'string' || !str.length) {
92
+ return null;
93
+ }
94
+
95
+ if (str.indexOf('git@gist') !== -1 || str.indexOf('//gist') !== -1) {
96
+ return null;
97
+ }
98
+
99
+ // parse the URL
100
+ var obj = url.parse(str);
101
+ if (typeof obj.path !== 'string' || !obj.path.length || typeof obj.pathname !== 'string' || !obj.pathname.length) {
102
+ return null;
103
+ }
104
+
105
+ if (!obj.host && (/^git@/).test(str) === true) {
106
+ // return the correct host for git@ URLs
107
+ obj.host = url.parse('http://' + str.replace(/git@([^:]+):/, '$1/')).host;
108
+ }
109
+
110
+ obj.path = trimSlash(obj.path);
111
+ obj.pathname = trimSlash(obj.pathname);
112
+ obj.filepath = null;
113
+
114
+ if (obj.path.indexOf('repos') === 0) {
115
+ obj.path = obj.path.slice(6);
116
+ }
117
+
118
+ var seg = obj.path.split('/').filter(Boolean);
119
+ var hasBlob = seg[2] === 'blob';
120
+ if (hasBlob && !isChecksum(seg[3])) {
121
+ obj.branch = seg[3];
122
+ if (seg.length > 4) {
123
+ obj.filepath = seg.slice(4).join('/');
124
+ }
125
+ }
126
+
127
+ var blob = str.indexOf('blob');
128
+ if (hasBlob && blob !== -1) {
129
+ obj.blob = str.slice(blob + 5);
130
+ }
131
+
132
+ var hasTree = seg[2] === 'tree';
133
+ var tree = str.indexOf('tree');
134
+ if (hasTree && tree !== -1) {
135
+ var idx = tree + 5;
136
+ var branch = str.slice(idx);
137
+ var slash = branch.indexOf('/');
138
+ if (slash !== -1) {
139
+ branch = branch.slice(0, slash);
140
+ }
141
+ obj.branch = branch;
142
+ }
143
+
144
+ obj.owner = owner(seg[0]);
145
+ obj.name = name(seg[1]);
146
+
147
+ if (seg.length > 1 && obj.owner && obj.name) {
148
+ obj.repo = obj.owner + '/' + obj.name;
149
+ } else {
150
+ var href = obj.href.split(':');
151
+ if (href.length === 2 && obj.href.indexOf('//') === -1) {
152
+ obj.repo = obj.repo || href[href.length - 1];
153
+ var repoSegments = obj.repo.split('/');
154
+ obj.owner = repoSegments[0];
155
+ obj.name = repoSegments[1];
156
+
157
+ } else {
158
+ var match = obj.href.match(/\/([^/]*)$/);
159
+ obj.owner = match ? match[1] : null;
160
+ obj.repo = null;
161
+ }
162
+
163
+ if (obj.repo && (!obj.owner || !obj.name)) {
164
+ var segs = obj.repo.split('/');
165
+ if (segs.length === 2) {
166
+ obj.owner = segs[0];
167
+ obj.name = segs[1];
168
+ }
169
+ }
170
+ }
171
+
172
+ if (!obj.branch) {
173
+ obj.branch = seg[2] || getBranch(obj.path, obj);
174
+ if (seg.length > 3) {
175
+ obj.filepath = seg.slice(3).join('/');
176
+ }
177
+ }
178
+
179
+ obj.host = obj.host || 'github.com';
180
+ obj.owner = obj.owner || null;
181
+ obj.name = obj.name || null;
182
+ obj.repository = obj.repo;
183
+ return obj;
184
+ }
185
+
186
+ parseGithubUrl$1 = function parseGithubUrl(str) {
187
+ if (!cache[str]) {
188
+ cache[str] = parse(str);
189
+ }
190
+ return cache[str];
191
+ };
192
+ return parseGithubUrl$1;
193
+ }
194
+
195
+ var parseGithubUrlExports = requireParseGithubUrl();
196
+ var parseGithubUrl = /*@__PURE__*/getDefaultExportFromCjs(parseGithubUrlExports);
197
+
198
+ function inferGitContext() {
199
+ if (!isGitRepository()) {
200
+ throw new Error('Not git repository detected.');
201
+ }
202
+ const remoteUrl = getRemoteUrl();
203
+ const parsed = parseGithubUrl(remoteUrl);
204
+ if (!parsed || !parsed.owner || !parsed.repo) {
205
+ throw new Error(`Could not parse GitHub URL: ${remoteUrl}. Expected format: https://github.com/owner/repo or git@github.com:owner/repo`);
206
+ }
207
+ const { owner, repo } = parsed;
208
+ const sha = getCurrentSha();
209
+ // repo is parsed as owner/repo but we want to use just the repo name
210
+ const repoName = repo.replace(`${owner}/`, '');
211
+ return { owner, repo: repoName, sha };
212
+ }
213
+ function isGitRepository() {
214
+ try {
215
+ execSync('git rev-parse --git-dir', { stdio: 'ignore' });
216
+ return true;
217
+ }
218
+ catch {
219
+ return false;
220
+ }
221
+ }
222
+ function getRemoteUrl() {
223
+ try {
224
+ const remoteUrl = execSync('git remote get-url origin', {
225
+ encoding: 'utf8',
226
+ stdio: 'pipe'
227
+ }).trim();
228
+ if (!remoteUrl) {
229
+ throw new Error('No origin remote found');
230
+ }
231
+ return remoteUrl;
232
+ }
233
+ catch {
234
+ throw new Error('Could not determine git remote URL. Please ensure you have an origin remote configured.');
235
+ }
236
+ }
237
+ function getCurrentSha() {
238
+ try {
239
+ return execSync('git rev-parse HEAD', {
240
+ encoding: 'utf8',
241
+ stdio: 'pipe'
242
+ }).trim();
243
+ }
244
+ catch {
245
+ throw new Error('Could not determine current commit SHA');
246
+ }
247
+ }
248
+
249
+ const options = {
250
+ url: {
251
+ type: 'string',
252
+ required: true
253
+ },
254
+ token: {
255
+ type: 'string',
256
+ required: true,
257
+ default: process.env.XCELERA_TOKEN
258
+ }
259
+ };
260
+ const { positionals, values } = parseArgs({
261
+ options,
262
+ allowPositionals: true,
263
+ args: process.argv.slice(2)
264
+ });
265
+ const command = positionals[0];
266
+ if (!command) {
267
+ console.error('A command is required. Only "audit" is currently supported.');
268
+ printHelp();
269
+ process.exit(1);
270
+ }
271
+ if (command === 'help') {
272
+ printHelp();
273
+ }
274
+ if (command !== 'audit') {
275
+ console.error('Invalid command. Only "audit" is currently supported.');
276
+ printHelp();
277
+ process.exit(1);
278
+ }
279
+ const { url, token } = values;
280
+ if (!url) {
281
+ console.error('URL is required. Use --url <url> to specify the URL to audit.');
282
+ process.exit(1);
283
+ }
284
+ if (!token) {
285
+ console.error('A token is required. Use --token or set XCELERA_TOKEN environment variable.');
286
+ process.exit(1);
287
+ }
288
+ try {
289
+ const githubContext = inferGitContext();
290
+ await requestAudit(url, token, githubContext);
291
+ console.log('✅ Audit scheduled successfully!');
292
+ }
293
+ catch (error) {
294
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
295
+ console.error(`❌ ${errorMessage}`);
296
+ process.exit(1);
297
+ }
298
+ function printHelp() {
299
+ console.log('Usage: xcelera audit --url <url> [--token <token>]');
300
+ console.log('');
301
+ console.log('Options:');
302
+ console.log(' --token <token> The xcelera API token to use for authentication.');
303
+ console.log('Can also be set with the XCELERA_TOKEN environment variable.');
304
+ console.log(' --url <url> The URL to audit.');
305
+ console.log('');
306
+ }
307
+ //# sourceMappingURL=cli.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xcelera/cli",
3
3
  "description": "CLI for xcelera.dev",
4
- "version": "1.2.0",
4
+ "version": "1.2.2",
5
5
  "author": "",
6
6
  "type": "module",
7
7
  "repository": {
@@ -27,7 +27,6 @@
27
27
  "node": ">=20"
28
28
  },
29
29
  "scripts": {
30
- "bundle": "npm run format:write && npm run package",
31
30
  "ci-test": "NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 npx jest --passWithNoTests",
32
31
  "coverage": "npx make-coverage-badge --output-path ./badges/coverage.svg",
33
32
  "format:write": "npx prettier --write .",