mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-11-10 08:27:27 +00:00
Some checks failed
CodeQL / Analyze (python) (push) Waiting to run
Gitleaks / gitleaks (push) Waiting to run
Publish / Classify release event (push) Waiting to run
Publish / RC guard (marker + release-PR skip) (push) Blocked by required conditions
Publish / ci (push) Blocked by required conditions
Publish / Build & Push RC Docker images (push) Blocked by required conditions
Publish / Publish to npm (push) Blocked by required conditions
Scorecard / Scorecard analysis (push) Waiting to run
Trivy Image Scan / Trivy (gitnexus-cli) (push) Waiting to run
Trivy Image Scan / Trivy (gitnexus-web) (push) Waiting to run
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
Devcontainer Smoke / Config-transform unit tests (push) Has been cancelled
Devcontainer Smoke / Build devcontainer image (default) (push) Has been cancelled
Devcontainer Smoke / Build devcontainer image (ui) (push) Has been cancelled
Publish Development Images / publish (core) (push) Has been cancelled
Publish Development Images / publish (ui) (push) Has been cancelled
Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
138 lines
4.5 KiB
TypeScript
138 lines
4.5 KiB
TypeScript
import { execFileSync, spawnSync } from 'node:child_process';
|
|
import { mkdtempSync, readFileSync, rmSync } from 'node:fs';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
import { load } from 'js-yaml';
|
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
|
|
const workflow = load(
|
|
readFileSync(path.resolve(__dirname, '../../../.github/workflows/publish.yml'), 'utf8'),
|
|
) as { jobs: { publish: { steps: { id?: string; run?: string }[] } } };
|
|
const versionStep = workflow.jobs.publish.steps.find((step) => step.id === 'rc-version');
|
|
if (!versionStep?.run) throw new Error('Missing RC version resolver');
|
|
const script = versionStep.run;
|
|
|
|
// Execute the workflow's actual resolver against real Git tags, with npm
|
|
// metadata held behind a completed publish as in run 39472555350.
|
|
describe.skipIf(process.platform === 'win32')('publish.yml RC version allocation', () => {
|
|
let dir: string;
|
|
|
|
beforeEach(() => {
|
|
dir = mkdtempSync(path.join(os.tmpdir(), 'gitnexus-rc-version-'));
|
|
execFileSync('git', ['init', '--quiet', dir]);
|
|
execFileSync(
|
|
'git',
|
|
[
|
|
'-c',
|
|
'user.name=Test',
|
|
'-c',
|
|
'user.email=test@example.com',
|
|
'-c',
|
|
'commit.gpgsign=false',
|
|
'commit',
|
|
'--quiet',
|
|
'--allow-empty',
|
|
'-m',
|
|
'fixture',
|
|
],
|
|
{ cwd: dir },
|
|
);
|
|
});
|
|
|
|
afterEach(() => rmSync(dir, { recursive: true, force: true }));
|
|
|
|
function resolve(versions: string[] | string, tags: string[], existingVersion = '') {
|
|
for (const tag of tags) execFileSync('git', ['tag', tag], { cwd: dir });
|
|
return spawnSync(
|
|
'bash',
|
|
[
|
|
'-c',
|
|
`
|
|
npm() {
|
|
case "$*" in
|
|
"view gitnexus version") echo '1.6.12' ;;
|
|
"view gitnexus versions --json") printf '%s' "$MOCK_VERSIONS" ;;
|
|
"view gitnexus@$MOCK_EXISTING_VERSION version") echo "$MOCK_EXISTING_VERSION" ;;
|
|
"view gitnexus@"*" version") echo 'E404 not found' >&2; return 1 ;;
|
|
*) echo "Unexpected npm invocation: $*" >&2; return 2 ;;
|
|
esac
|
|
}
|
|
npx() {
|
|
if [ "$*" = "--yes -p semver@7 semver -i patch 1.6.12" ]; then
|
|
echo '1.6.13'
|
|
else
|
|
echo "Unexpected npx invocation: $*" >&2; return 2
|
|
fi
|
|
}
|
|
${script.replaceAll('/tmp/', `${dir}/`)}
|
|
`,
|
|
],
|
|
{
|
|
cwd: dir,
|
|
encoding: 'utf8',
|
|
timeout: 10_000,
|
|
env: {
|
|
...process.env,
|
|
EVENT_NAME: 'push',
|
|
BUMP_INPUT: '',
|
|
PKG_NAME: 'gitnexus',
|
|
GITHUB_OUTPUT: path.join(dir, 'output'),
|
|
MOCK_VERSIONS: JSON.stringify(versions),
|
|
MOCK_EXISTING_VERSION: existingVersion,
|
|
},
|
|
},
|
|
);
|
|
}
|
|
|
|
it.each([
|
|
{
|
|
name: 'skips an existing tag while npm is still processing its publication',
|
|
versions: ['1.6.13-rc.135'],
|
|
tags: ['v1.6.13-rc.136'],
|
|
next: 137,
|
|
},
|
|
{
|
|
name: 'uses the highest reserved tag across multiple pending publications',
|
|
versions: ['1.6.13-rc.135'],
|
|
tags: ['v1.6.13-rc.136', 'v1.6.13-rc.138'],
|
|
next: 139,
|
|
},
|
|
{
|
|
name: 'keeps npm as the floor when the registry is ahead of Git tags',
|
|
versions: ['1.6.13-rc.139'],
|
|
tags: ['v1.6.13-rc.136'],
|
|
next: 140,
|
|
},
|
|
{
|
|
name: 'handles a single version returned by npm',
|
|
versions: '1.6.13-rc.135',
|
|
tags: [],
|
|
next: 136,
|
|
},
|
|
{
|
|
name: 'starts at rc.1 when neither source reserves the selected base',
|
|
versions: [],
|
|
tags: ['v1.6.12-rc.999', 'v1.7.0-rc.999', 'v1.6.13-beta.999'],
|
|
next: 1,
|
|
},
|
|
{
|
|
name: 'ignores tags with a nonnumeric RC suffix',
|
|
versions: ['1.6.13-rc.135'],
|
|
tags: ['v1.6.13-rc.999-extra', 'v1.6.13-rc.999.1'],
|
|
next: 136,
|
|
},
|
|
])('$name', ({ versions, tags, next }) => {
|
|
const result = resolve(versions, tags);
|
|
expect(result.status, result.stderr).toBe(0);
|
|
const version = `1.6.13-rc.${next}`;
|
|
expect(readFileSync(path.join(dir, 'output'), 'utf8')).toContain(`rc_version=${version}\n`);
|
|
// The allocated name must be available to the following tag-creation step.
|
|
execFileSync('git', ['tag', `v${version}`], { cwd: dir });
|
|
});
|
|
|
|
it('still aborts when the allocated version appears in npm before publication', () => {
|
|
const result = resolve(['1.6.13-rc.135'], ['v1.6.13-rc.136'], '1.6.13-rc.137');
|
|
expect(result.status).toBe(1);
|
|
expect(result.stdout).toContain('Version 1.6.13-rc.137 already exists on npm');
|
|
});
|
|
});
|