Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion action/index.js

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions src/model/project.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import * as core from '@actions/core';
import Unity from './unity';
import Input from './input';
import Action from './action';

class Project {
static get relativePath() {
const projectPath = Input.getFromUser().then(result => result.projectPath);
// Todo - properly use Input for this.
const projectPath = core.getInput('projectPath') || '.';

return `${projectPath}`;
}
Expand Down
20 changes: 19 additions & 1 deletion src/model/system.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import * as core from '@actions/core';
import { exec } from '@actions/exec';

class System {
static async run(command, arguments_, options) {
let result = '';
let error = '';
let debug = '';

const listeners = {
stdout: dataBuffer => {
Expand All @@ -12,13 +14,29 @@ class System {
stderr: dataBuffer => {
error += dataBuffer.toString();
},
debug: dataString => {
debug += dataString.toString();
},
};

const exitCode = await exec(command, arguments_, { ...options, listeners });
const exitCode = await exec(command, arguments_, { silent: true, listeners, ...options });

if (debug !== '') {
core.debug(debug);
}

if (result !== '') {
core.info(result);
}

if (exitCode !== 0) {
throw new Error(error);
}

if (error !== '') {
core.warning(error);
}

return result;
}
}
Expand Down
48 changes: 48 additions & 0 deletions src/model/system.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import * as core from '@actions/core';
import System from './system';

jest.spyOn(core, 'debug').mockImplementation(() => {});
const info = jest.spyOn(core, 'info').mockImplementation(() => {});
jest.spyOn(core, 'warning').mockImplementation(() => {});
jest.spyOn(core, 'error').mockImplementation(() => {});

afterEach(() => {
jest.clearAllMocks();
});

describe('System', () => {
describe('run', () => {
it('runs a command successfully', async () => {
await expect(System.run('true')).resolves.not.toBeNull();
});

it('outputs results', async () => {
await expect(System.run('echo test')).resolves.toStrictEqual('test\n');
});

it('throws on when error code is not 0', async () => {
await expect(System.run('false')).rejects.toThrowError();
});

it('throws when no arguments are given', async () => {
await expect(System.run()).rejects.toThrowError();
});

it('outputs info', async () => {
await expect(System.run('echo test')).resolves.not.toBeNull();
expect(info).toHaveBeenLastCalledWith('test\n');
});

it('outputs info only once', async () => {
await expect(System.run('echo 1')).resolves.not.toBeNull();
expect(info).toHaveBeenCalledTimes(1);
expect(info).toHaveBeenLastCalledWith('1\n');

info.mockClear();
await expect(System.run('echo 2')).resolves.not.toBeNull();
await expect(System.run('echo 3')).resolves.not.toBeNull();
expect(info).toHaveBeenCalledTimes(2);
expect(info).toHaveBeenLastCalledWith('3\n');
});
});
});
27 changes: 23 additions & 4 deletions src/model/versioning.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export default class Versioning {
* @See: https://semver.org/
*/
static async generateSemanticVersion() {
await this.fetchAll();
await this.fetch();

if (await this.isDirty()) {
throw new Error('Branch is dirty. Refusing to base semantic version on uncommitted changes');
Expand Down Expand Up @@ -128,8 +128,20 @@ export default class Versioning {
}
}

static async fetchAll() {
await System.run('git', ['fetch', '--all']);
/**
* Retrieves refs from the configured remote.
*
* Fetch unshallow for incomplete repository, but fall back to normal fetch.
*
* Note: `--all` should not be used, and would break fetching for push event.
*/
static async fetch() {
try {
await System.run('git', ['fetch', '--unshallow']);
} catch (error) {
core.warning(error);
await System.run('git', ['fetch']);
}
}

/**
Expand All @@ -141,7 +153,14 @@ export default class Versioning {
* identifies the current commit.
*/
static async getVersionDescription() {
return System.run('git', ['describe', '--long', '--tags', '--always', `origin/${this.branch}`]);
return System.run('git', [
'describe',
'--long',
'--tags',
'--always',
'--debug',
`origin/${this.branch}`,
]);
}

/**
Expand Down
53 changes: 51 additions & 2 deletions src/model/versioning.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as core from '@actions/core';
import NotImplementedException from './error/not-implemented-exception';
import System from './system';
import Versioning from './versioning';
Expand Down Expand Up @@ -194,10 +195,58 @@ describe('Versioning', () => {
});
});

describe('fetchAll', () => {
describe('fetch', () => {
it('awaits the command', async () => {
jest.spyOn(core, 'warning').mockImplementation(() => {});
jest.spyOn(System, 'run').mockResolvedValue(null);
await expect(Versioning.fetchAll()).resolves.not.toThrow();
await expect(Versioning.fetch()).resolves.not.toThrow();
});

it('falls back to the second strategy when the first fails', async () => {
jest.spyOn(core, 'warning').mockImplementation(() => {});
const gitFetch = jest
.spyOn(System, 'run')
.mockResolvedValue(null)
.mockRejectedValueOnce(null);

await expect(Versioning.fetch()).resolves.not.toThrow();
expect(gitFetch).toHaveBeenCalledTimes(2);
});
});

describe('generateSemanticVersion', () => {
it('returns a proper version from description', async () => {
jest.spyOn(System, 'run').mockResolvedValue(null);
jest.spyOn(core, 'info').mockImplementation(() => {});
jest.spyOn(Versioning, 'isDirty').mockResolvedValue(false);
jest.spyOn(Versioning, 'hasAnyVersionTags').mockResolvedValue(true);
jest.spyOn(Versioning, 'getTotalNumberOfCommits').mockResolvedValue(2);
jest.spyOn(Versioning, 'parseSemanticVersion').mockResolvedValue({
match: '0.1-2-g1b345678',
tag: '0.1',
commits: '2',
hash: '1b345678',
});

await expect(Versioning.generateSemanticVersion()).resolves.toStrictEqual('0.1.2');
});

it('throws when dirty', async () => {
jest.spyOn(System, 'run').mockResolvedValue(null);
jest.spyOn(core, 'info').mockImplementation(() => {});
jest.spyOn(Versioning, 'isDirty').mockResolvedValue(true);
await expect(Versioning.generateSemanticVersion()).rejects.toThrowError();
});

it('falls back to commits only, when no tags are present', async () => {
const commits = Math.round(Math.random() * 10);
jest.spyOn(System, 'run').mockResolvedValue(null);
jest.spyOn(core, 'info').mockImplementation(() => {});
jest.spyOn(Versioning, 'isDirty').mockResolvedValue(false);
jest.spyOn(Versioning, 'hasAnyVersionTags').mockResolvedValue(false);
jest.spyOn(Versioning, 'getTotalNumberOfCommits').mockResolvedValue(commits);

await expect(Versioning.generateSemanticVersion()).resolves.toStrictEqual(`0.0.${commits}`);
});
});

Expand Down