Skip to content

Commit

Permalink
Merge pull request #10 from technote-space/release/v0.0.9
Browse files Browse the repository at this point in the history
Release/v0.0.9
  • Loading branch information
technote-space committed Sep 23, 2019
2 parents 56b3c99 + 79e3deb commit 6fccde9
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 31 deletions.
125 changes: 110 additions & 15 deletions __tests__/api-helper.test.ts
Expand Up @@ -9,27 +9,28 @@ import { testLogger } from './util';
import { ApiHelper, Logger } from '../src';
import global from './global';

const context = getContext({
ref: 'refs/heads/test',
repo: {
owner: 'hello',
repo: 'world',
},
sha: '7638417db6d59f3c431d3e1f261cc637155684cd',
payload: {
sender: {
type: 'User',
login: 'octocat',
},
},
});
const octokit = new GitHub('');

describe('ApiHelper', () => {
disableNetConnect(nock);
testEnv();
testLogger();

const helper = new ApiHelper(new Logger());
const context = getContext({
ref: 'refs/heads/test',
repo: {
owner: 'hello',
repo: 'world',
},
sha: '7638417db6d59f3c431d3e1f261cc637155684cd',
payload: {
sender: {
type: 'User',
login: 'octocat',
},
},
});
const octokit = new GitHub('');

/**
* @param {T} data data
Expand Down Expand Up @@ -269,6 +270,7 @@ describe('ApiHelper', () => {
});

it('should commit', async() => {
const mockStdout = jest.spyOn(global.mockStdout, 'write');
nock('https://api.github.com')
.persist()
.get('/repos/hello/world/branches/test/protection')
Expand All @@ -287,6 +289,17 @@ describe('ApiHelper', () => {
.reply(200, () => getApiFixture(path.resolve(__dirname, 'fixtures'), 'repos.git.refs'));

expect(await helper.commit(path.resolve(__dirname, 'fixtures'), 'test commit message', ['build1.json', 'build2.json'], octokit, context)).toBeTruthy();
expect(mockStdout).toBeCalledTimes(10);
expect(mockStdout.mock.calls[0][0]).toBe('##[group]Start push to branch [test]' + EOL);
expect(mockStdout.mock.calls[1][0]).toBe('##[endgroup]' + EOL);
expect(mockStdout.mock.calls[2][0]).toBe('##[group]Creating blobs' + EOL);
expect(mockStdout.mock.calls[3][0]).toBe('##[endgroup]' + EOL);
expect(mockStdout.mock.calls[4][0]).toBe('##[group]Creating tree' + EOL);
expect(mockStdout.mock.calls[5][0]).toBe('##[endgroup]' + EOL);
expect(mockStdout.mock.calls[6][0]).toBe('##[group]Creating commit [cd8274d15fa3ae2ab983129fb037999f264ba9a7]' + EOL);
expect(mockStdout.mock.calls[7][0]).toBe('##[endgroup]' + EOL);
expect(mockStdout.mock.calls[8][0]).toBe('##[group]Updating ref [heads%2Ftest] [7638417db6d59f3c431d3e1f261cc637155684cd]' + EOL);
expect(mockStdout.mock.calls[9][0]).toBe('##[endgroup]' + EOL);
});
});

Expand Down Expand Up @@ -338,3 +351,85 @@ describe('ApiHelper', () => {
});
});
});

describe('ApiHelper with params', () => {
disableNetConnect(nock);
testEnv();
testLogger();

const helper = new ApiHelper(new Logger(), {branch: 'test-branch', sender: 'test-sender', refForUpdate: 'test-ref'});

describe('commit', () => {
it('should commit', async() => {
const fn1 = jest.fn();
const fn2 = jest.fn();
const mockStdout = jest.spyOn(global.mockStdout, 'write');
nock('https://api.github.com')
.persist()
.get('/repos/hello/world/branches/test/protection')
.reply(404)
.post('/repos/hello/world/git/blobs')
.reply(201, () => {
return getApiFixture(path.resolve(__dirname, 'fixtures'), 'repos.git.blobs');
})
.get('/repos/hello/world/git/commits/7638417db6d59f3c431d3e1f261cc637155684cd')
.reply(200, () => getApiFixture(path.resolve(__dirname, 'fixtures'), 'repos.git.commits.get'))
.post('/repos/hello/world/git/trees')
.reply(201, () => getApiFixture(path.resolve(__dirname, 'fixtures'), 'repos.git.trees'))
.post('/repos/hello/world/git/commits')
.reply(201, () => getApiFixture(path.resolve(__dirname, 'fixtures'), 'repos.git.commits'))
.patch('/repos/hello/world/git/refs/' + encodeURIComponent('heads/test'))
.reply(200, () => {
fn1();
return getApiFixture(path.resolve(__dirname, 'fixtures'), 'repos.git.refs');
})
.patch('/repos/hello/world/git/refs/' + encodeURIComponent('test-ref'))
.reply(200, () => {
fn2();
return getApiFixture(path.resolve(__dirname, 'fixtures'), 'repos.git.refs');
});

expect(await helper.commit(path.resolve(__dirname, 'fixtures'), 'test commit message', ['build1.json', 'build2.json'], octokit, context)).toBeTruthy();
expect(fn1).not.toBeCalled();
expect(fn2).toBeCalledTimes(1);
expect(mockStdout).toBeCalledTimes(10);
expect(mockStdout.mock.calls[0][0]).toBe('##[group]Start push to branch [test-branch]' + EOL);
expect(mockStdout.mock.calls[1][0]).toBe('##[endgroup]' + EOL);
expect(mockStdout.mock.calls[2][0]).toBe('##[group]Creating blobs' + EOL);
expect(mockStdout.mock.calls[3][0]).toBe('##[endgroup]' + EOL);
expect(mockStdout.mock.calls[4][0]).toBe('##[group]Creating tree' + EOL);
expect(mockStdout.mock.calls[5][0]).toBe('##[endgroup]' + EOL);
expect(mockStdout.mock.calls[6][0]).toBe('##[group]Creating commit [cd8274d15fa3ae2ab983129fb037999f264ba9a7]' + EOL);
expect(mockStdout.mock.calls[7][0]).toBe('##[endgroup]' + EOL);
expect(mockStdout.mock.calls[8][0]).toBe('##[group]Updating ref [test-ref] [7638417db6d59f3c431d3e1f261cc637155684cd]' + EOL);
expect(mockStdout.mock.calls[9][0]).toBe('##[endgroup]' + EOL);
});
});

describe('getUser', () => {
it('should get user', async() => {
const fn1 = jest.fn();
const fn2 = jest.fn();
nock('https://api.github.com')
.persist()
.get('/users/octocat')
.reply(200, () => {
fn1();
return getApiFixture(path.resolve(__dirname, 'fixtures'), 'users.get');
})
.get('/users/test-sender')
.reply(200, () => {
fn2();
return getApiFixture(path.resolve(__dirname, 'fixtures'), 'users.get');
});

const user = await helper.getUser(octokit, context);
expect(fn1).not.toBeCalled();
expect(fn2).toBeCalledTimes(1);
expect(user.login).toBe('octocat');
expect(user.email).toBe('octocat@github.com');
expect(user.name).toBe('monalisa octocat');
expect(user.id).toBe(1);
});
});
});
4 changes: 0 additions & 4 deletions jest.setup.ts
Expand Up @@ -21,8 +21,4 @@ jest.mock('child_process', () => ({
exec: global.mockChildProcess.exec,
}));

global.console.log = jest.fn();
global.console.warn = jest.fn();
global.console.error = jest.fn();

process.env.GITHUB_ACTOR = 'octocat';
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "@technote-space/github-action-helper",
"version": "0.0.8",
"version": "0.0.9",
"description": "Helper to filter GitHub Action.",
"author": "Technote <technote.space@gmail.com> (https://technote.space)",
"license": "MIT",
Expand Down
51 changes: 40 additions & 11 deletions src/api-helper.ts
Expand Up @@ -4,20 +4,50 @@ import { GitHub } from '@actions/github/lib/github';
import { Context } from '@actions/github/lib/context';
import { Response, GitCreateTreeResponse, GitCreateCommitResponse, GitGetCommitResponse } from '@octokit/rest';
import { Logger } from './logger';
import { getBranch, getRefForUpdate, getSender } from './utils';
import { getBranch, getSender, getRefForUpdate } from './utils';

/**
* Commit
*/
export default class ApiHelper {

private readonly branch?: string | undefined = undefined;
private readonly sender?: string | undefined = undefined;
private readonly refForUpdate?: string | undefined = undefined;

/**
* @param {Logger} logger logger
* @param {object} options options
* @param {string|undefined} options.branch branch
* @param {string|undefined} options.sender sender
* @param {string|undefined} options.refForUpdate ref for update
*/
constructor(private logger: Logger) {

constructor(private readonly logger: Logger, options?: { branch?: string; sender?: string; refForUpdate?: string }) {
if (options) {
this.branch = options.branch;
this.sender = options.sender;
this.refForUpdate = options.refForUpdate;
}
}

/**
* @param {Context} context context
* @return {string} branch
*/
private getBranch = (context: Context): string => this.branch ? this.branch : getBranch(context);

/**
* @param {Context} context context
* @return {string|boolean} sender
*/
private getSender = (context: Context): string | false => this.sender ? this.sender : getSender(context);

/**
* @param {Context} context context
* @return {string} ref for update
*/
private getRefForUpdate = (context: Context): string => this.refForUpdate ? this.refForUpdate : getRefForUpdate(context);

/**
* @param {string} rootDir root dir
* @param {string} filepath filepath
Expand Down Expand Up @@ -108,7 +138,7 @@ export default class ApiHelper {
await octokit.git.updateRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: getRefForUpdate(context),
ref: this.getRefForUpdate(context),
sha: commit.data.sha,
});
};
Expand All @@ -119,14 +149,12 @@ export default class ApiHelper {
* @return {Promise<boolean>} result
*/
public checkProtected = async(octokit: GitHub, context: Context): Promise<boolean> => {
const branch = getBranch(context);

try {
// eslint-disable-next-line no-magic-numbers
return 200 === (await octokit.repos.getBranchProtection({
owner: context.repo.owner,
repo: context.repo.repo,
branch,
branch: this.getBranch(context),
})).status;
} catch (error) {
return false;
Expand All @@ -148,11 +176,11 @@ export default class ApiHelper {
}

if (await this.checkProtected(octokit, context)) {
this.logger.warn('Branch [%s] is protected', getBranch(context));
this.logger.warn('Branch [%s] is protected', this.getBranch(context));
return false;
}

this.logger.startProcess('Start push to branch [%s]', getBranch(context));
this.logger.startProcess('Start push to branch [%s]', this.getBranch(context));

this.logger.startProcess('Creating blobs');
const blobs = await this.filesToBlobs(rootDir, files, octokit, context);
Expand All @@ -163,9 +191,10 @@ export default class ApiHelper {
this.logger.startProcess('Creating commit [%s]', tree.data.sha);
const commit = await this.createCommit(commitMessage, tree, octokit, context);

this.logger.startProcess('Updating ref [%s] [%s]', getRefForUpdate(context), commit.data.sha);
this.logger.startProcess('Updating ref [%s] [%s]', this.getRefForUpdate(context), commit.data.sha);
await this.updateRef(commit, octokit, context);

this.logger.endProcess();
return true;
};

Expand All @@ -175,7 +204,7 @@ export default class ApiHelper {
* @return {Promise<{ login: string, email: string, name: string, id: number }>} user
*/
public getUser = async(octokit: GitHub, context: Context): Promise<{ login: string; email: string; name: string; id: number }> => {
const sender = getSender(context);
const sender = this.getSender(context);
if (false === sender) {
throw new Error('Sender is not valid.');
}
Expand Down

0 comments on commit 6fccde9

Please sign in to comment.