Skip to content

Commit

Permalink
test: improve reliability
Browse files Browse the repository at this point in the history
  • Loading branch information
privatenumber authored and name committed Nov 3, 2024
1 parent 9b995d2 commit 619eb9d
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 79 deletions.
8 changes: 3 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
pull_request:
branches: [master, develop]

permissions:
contents: write

jobs:
test:
name: Test
Expand Down Expand Up @@ -34,11 +37,6 @@ jobs:
- name: Type check
run: pnpm type-check

- name: Setup Git # Only used by the last test
run: |
git config --global user.name "GitHub Actions"
git config --global user.email "<>"
- name: Build
run: pnpm build

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"clean-pkg-json": "^1.2.0",
"cleye": "^1.3.2",
"execa": "^8.0.1",
"fs-fixture": "^2.5.0",
"fs-fixture": "^2.6.0",
"lintroll": "^1.10.0",
"manten": "^1.3.0",
"npm-packlist": "^5.1.1",
Expand Down
10 changes: 5 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 9 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,15 @@ const { stringify } = JSON;
const localTemporaryBranch = `git-publish/${publishBranch}-${Date.now()}`;
let success = false;

// Validate remote exists
let remoteUrl;
try {
const getRemoteUrl = await execa('git', ['remote', 'get-url', remote]);
remoteUrl = getRemoteUrl.stdout.trim();
} catch {
throw new Error(`Git remote ${stringify(remote)} does not exist`);
}

// In the try-finally block in case it modifies the working tree
// On failure, they will be reverted by the hard reset
try {
Expand Down Expand Up @@ -258,14 +267,6 @@ const { stringify } = JSON;
}

if (success) {
let remoteUrl = remote;

// If the "remote" flag contains an alias, resolve it to a URL
try {
const { stdout } = await execa('git', ['remote', 'get-url', remoteUrl]);
remoteUrl = stdout.trim();
} catch {}

const parsedGitUrl = remoteUrl.match(/github\.com:(.+)\.git$/);

if (parsedGitUrl) {
Expand Down
81 changes: 21 additions & 60 deletions tests/index.ts
Original file line number Diff line number Diff line change
@@ -1,100 +1,61 @@
import path from 'path';
import { execa, type Options } from 'execa';
import path from 'node:path';
import fs from 'node:fs/promises';
import { describe, expect } from 'manten';
import { createFixture } from 'fs-fixture';

const gitPublish = path.resolve('./dist/index.js');

const createGit = async (cwd: string) => {
const git = (
command: string,
args?: string[],
options?: Options,
) => (
execa(
'git',
[command, ...(args || [])],
{
cwd,
...options,
},
)
);

await git(
'init',
[
// In case of different default branch name
'--initial-branch=master',
],
);

await git('config', ['user.name', 'name']);
await git('config', ['user.email', 'email']);

return git;
};
import { createGit } from './utils/create-git.js';
import { gitPublish } from './utils/git-publish.js';

describe('git-publish', ({ describe, test }) => {
describe('Error cases', ({ test }) => {
test('Fails if not in git repository', async () => {
const fixture = await createFixture();
await using fixture = await createFixture();

const gitPublishProcess = await execa(gitPublish, {
cwd: fixture.path,
reject: false,
});
const gitPublishProcess = await gitPublish(fixture.path);

expect(gitPublishProcess.exitCode).toBe(1);
expect(gitPublishProcess.stderr).toBe('Error: Not in a git repository');

await fixture.rm();
});

test('Fails if no package.json found', async () => {
const fixture = await createFixture();
await using fixture = await createFixture();

await createGit(fixture.path);

const gitPublishProcess = await execa(gitPublish, {
cwd: fixture.path,
reject: false,
});
const gitPublishProcess = await gitPublish(fixture.path);

expect(gitPublishProcess.exitCode).toBe(1);
expect(gitPublishProcess.stderr).toBe('Error: No package.json found in current working directory');

await fixture.rm();
});

test('Dirty working tree', async () => {
const fixture = await createFixture({
await using fixture = await createFixture({
'package.json': '{}',
});

const git = await createGit(fixture.path);
await git('add', ['package.json']);

const gitPublishProcess = await execa(gitPublish, {
cwd: fixture.path,
reject: false,
});
const gitPublishProcess = await gitPublish(fixture.path);

expect(gitPublishProcess.exitCode).toBe(1);
expect(gitPublishProcess.stderr).toBe('Error: Working tree is not clean');

await fixture.rm();
});
});

test('Publishes', async ({ onTestFail }) => {
// Requires git config author to be set
// This is set on the GitHub Action because locally, an author already exists

const gitPublishProcess = await execa(gitPublish, {
reject: false,
const fixture = await createFixture(process.cwd(), {
templateFilter: cpPath => !(
cpPath.endsWith(`${path.sep}node_modules`)
|| path.basename(cpPath) === '.git'
|| path.basename(cpPath) === 'dist'
),
});

await fs.symlink(path.resolve('node_modules'), fixture.getPath('node_modules'), 'dir');
await fs.symlink(path.resolve('.git'), fixture.getPath('.git'), 'dir');

const gitPublishProcess = await gitPublish(fixture.path);

onTestFail(() => {
console.log(gitPublishProcess);

Check warning on line 60 in tests/index.ts

View workflow job for this annotation

GitHub Actions / Test

Unexpected console statement
});
Expand Down
33 changes: 33 additions & 0 deletions tests/utils/create-git.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { execa, type Options } from 'execa';

export const createGit = async (
cwd: string,
) => {
const git = (
command: string,
args?: string[],
options?: Options,
) => (
execa(
'git',
[command, ...(args || [])],
{
cwd,
...options,
},
)
);

await git(
'init',
[
// In case of different default branch name
'--initial-branch=master',
],
);

await git('config', ['user.name', 'name']);
await git('config', ['user.email', 'email']);

return git;
};
16 changes: 16 additions & 0 deletions tests/utils/git-publish.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import path from 'node:path';
import { execa } from 'execa';

const gitPublishPath = path.resolve('./dist/index.js');

export const gitPublish = (
cwd: string,
) => execa(gitPublishPath, {
cwd,
reject: false,
// Remove CI env var which prevents Ink from rendering
env: {
PATH: process.env.PATH,
},
extendEnv: false,
});

0 comments on commit 619eb9d

Please sign in to comment.