Skip to content

Commit 89b5c0a

Browse files
Merge pull request #24 from technote-space/release/v1.0.4
Release/v1.0.4
2 parents 9334458 + 498f0d3 commit 89b5c0a

File tree

7 files changed

+97
-32
lines changed

7 files changed

+97
-32
lines changed

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@
66
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/technote-space/release-github-actions/blob/master/LICENSE)
77

88
GitHub actions to auto release.
9-
Once you publish the release, this action will run build and create branch automatically.
9+
Once you publish the release, this action will automatically
10+
1. Run build
11+
1. Create branch for release
12+
1. Change tag to release branch
13+
1. Change release tag
1014

1115
## Installation
1216
.github/workflows/release.yml
@@ -19,7 +23,7 @@ jobs:
1923
runs-on: ubuntu-latest
2024
steps:
2125
- name: Release GitHub Actions
22-
uses: technote-space/release-github-actions@v1.0.3
26+
uses: technote-space/release-github-actions@v1
2327
with:
2428
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
2529
```

__tests__/utils/misc.test.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ import {
66
getCommitMessage,
77
getCommitName,
88
getCommitEmail,
9+
getBranchName,
910
getWorkspace,
1011
getBuildCommands,
1112
getGitUrl,
1213
detectBuildCommand,
1314
getRepository,
1415
} from '../../src/utils/misc';
15-
import {DEFAULT_COMMIT_MESSAGE, DEFAULT_COMMIT_NAME, DEFAULT_COMMIT_EMAIL} from '../../src/constant';
16+
import {DEFAULT_COMMIT_MESSAGE, DEFAULT_COMMIT_NAME, DEFAULT_COMMIT_EMAIL, DEFAULT_BRANCH_NAME} from '../../src/constant';
1617

1718
const testEnv = () => {
1819
const OLD_ENV = process.env;
@@ -115,7 +116,7 @@ describe('getCommitMessage', () => {
115116
expect(getCommitMessage()).toBe('test');
116117
});
117118

118-
it('should get commit default message', () => {
119+
it('should get default commit message', () => {
119120
expect(getCommitMessage()).toBe(DEFAULT_COMMIT_MESSAGE);
120121
});
121122
});
@@ -128,7 +129,7 @@ describe('getCommitName', () => {
128129
expect(getCommitName()).toBe('test');
129130
});
130131

131-
it('should get commit default name', () => {
132+
it('should get default commit name', () => {
132133
expect(getCommitName()).toBe(DEFAULT_COMMIT_NAME);
133134
});
134135
});
@@ -141,11 +142,24 @@ describe('getCommitEmail', () => {
141142
expect(getCommitEmail()).toBe('test');
142143
});
143144

144-
it('should get commit default email', () => {
145+
it('should get default commit email', () => {
145146
expect(getCommitEmail()).toBe(DEFAULT_COMMIT_EMAIL);
146147
});
147148
});
148149

150+
describe('getBranchName', () => {
151+
testEnv();
152+
153+
it('should get branch name', () => {
154+
process.env.INPUT_BRANCH_NAME = 'test';
155+
expect(getBranchName()).toBe('test');
156+
});
157+
158+
it('should get default branch name', () => {
159+
expect(getBranchName()).toBe(DEFAULT_BRANCH_NAME);
160+
});
161+
});
162+
149163
describe('getWorkspace', () => {
150164
testEnv();
151165

action.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ inputs:
1717
COMMIT_EMAIL:
1818
description: Git commit email.
1919
default: '[email protected]'
20+
BRANCH_NAME:
21+
description: Branch name.
22+
default: 'gh-actions'
2023
runs:
2124
using: node12
2225
main: lib/main.js

src/constant.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export const DEFAULT_COMMIT_MESSAGE = 'feat: Build for release';
22
export const DEFAULT_COMMIT_NAME = 'GitHub Actions';
33
export const DEFAULT_COMMIT_EMAIL = '[email protected]';
4+
export const DEFAULT_BRANCH_NAME = 'gh-actions';
45
export const TARGET_EVENT_NAME = 'release';
56
export const TARGET_EVENT_ACTION = 'published';
67
export const SEARCH_BUILD_COMMAND_TARGETS = [

src/main.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import {setFailed} from '@actions/core' ;
2-
import {context} from '@actions/github' ;
1+
import {setFailed} from '@actions/core';
2+
import {context, GitHub} from '@actions/github';
33
import signale from 'signale';
44
import {deploy} from './utils/command';
55
import {isTargetEvent} from './utils/misc';
@@ -13,8 +13,13 @@ async function run() {
1313
return;
1414
}
1515

16+
if (typeof process.env.GITHUB_TOKEN === 'undefined' || process.env.GITHUB_TOKEN === '') {
17+
// noinspection ExceptionCaughtLocallyJS
18+
throw new Error(`Input required and not supplied: GITHUB_TOKEN`);
19+
}
20+
1621
signale.info(`Tag name: ${context.payload.release.tag_name}`);
17-
await deploy(context.payload.release.tag_name, context);
22+
await deploy(context.payload.release.tag_name, new GitHub(process.env.GITHUB_TOKEN), context);
1823
} catch (error) {
1924
setFailed(error.message);
2025
}

src/utils/command.ts

Lines changed: 50 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,25 @@ import fs from 'fs';
22
import path from 'path';
33
import signale from 'signale';
44
import {exec} from 'child_process';
5+
import {GitHub} from '@actions/github/lib/github';
56
import {Context} from '@actions/github/lib/context';
6-
import {getGitUrl, getRepository, getBuildCommands, getWorkspace, getCommitMessage, getCommitName, getCommitEmail, detectBuildCommand} from './misc';
7+
import {getGitUrl, getRepository, getBuildCommands, getWorkspace, getCommitMessage, getCommitName, getCommitEmail, getBranchName} from './misc';
78

8-
export const deploy = async (branch: string, context: Context) => {
9+
export const deploy = async (tagName: string, octokit: GitHub, context: Context) => {
910
const workDir = path.resolve(getWorkspace(), '.work');
1011
const buildDir = path.resolve(workDir, 'build');
1112
const pushDir = path.resolve(workDir, 'push');
12-
signale.info(`Deploying branch %s to %s`, branch, getRepository(context));
13+
const branchName = getBranchName();
14+
signale.info('Deploying branch %s to %s', branchName, getRepository(context));
1315

1416
fs.mkdirSync(pushDir, {recursive: true});
15-
if (!await cloneForBranch(pushDir, branch, context)) return;
17+
if (!await cloneForBranch(pushDir, branchName, context)) return;
1618
if (!await prepareFiles(buildDir, pushDir, context)) return;
1719
if (!await copyFiles(buildDir, pushDir)) return;
1820
if (!await config(pushDir)) return;
1921
if (!await commit(pushDir)) return;
20-
await push(pushDir, branch, context);
22+
if (!await push(pushDir, tagName, branchName, context)) return;
23+
await updateRelease(tagName, octokit, context);
2124
};
2225

2326
export const prepareFiles = async (buildDir: string, pushDir: string, context: Context): Promise<boolean> => {
@@ -29,26 +32,26 @@ export const prepareFiles = async (buildDir: string, pushDir: string, context: C
2932
return true;
3033
};
3134

32-
const cloneForBranch = async (pushDir: string, branch: string, context: Context): Promise<boolean> => {
33-
signale.info(`Cloning the branch %s from the remote repo`, branch);
35+
const cloneForBranch = async (pushDir: string, branchName: string, context: Context): Promise<boolean> => {
36+
signale.info('Cloning the branch %s from the remote repo', branchName);
3437

3538
const url = getGitUrl(context);
36-
await execAsync(`git -C ${pushDir} clone --quiet --branch=${branch} --depth=1 ${url} .`, true, 'git clone', true);
39+
await execAsync(`git -C ${pushDir} clone --quiet --branch=${branchName} --depth=1 ${url} .`, true, 'git clone', true);
3740

38-
const clonedBranch = await getBranchName(pushDir);
39-
if (branch !== clonedBranch) {
40-
signale.info(`remote branch ${branch} not found.`);
41-
signale.info(`now branch: ${clonedBranch}`);
41+
const clonedBranch = await getCurrentBranchName(pushDir);
42+
if (branchName !== clonedBranch) {
43+
signale.info('remote branch %s not found.', branchName);
44+
signale.info('now branch: %s', clonedBranch);
4245

4346
await execAsync(`rm -rdf ${pushDir}`);
4447
fs.mkdirSync(pushDir, {recursive: true});
4548
await gitInit(pushDir);
46-
await gitCheckout(pushDir, branch);
49+
await gitCheckout(pushDir, branchName);
4750
}
4851
return true;
4952
};
5053

51-
const getBranchName = async (pushDir: string): Promise<string> => {
54+
const getCurrentBranchName = async (pushDir: string): Promise<string> => {
5255
if (!fs.existsSync(path.resolve(pushDir, '.git'))) {
5356
return '';
5457
}
@@ -61,10 +64,10 @@ const gitInit = async (pushDir: string) => {
6164
await execAsync(`git -C ${pushDir} init .`);
6265
};
6366

64-
const gitCheckout = async (pushDir: string, branch: string) => {
65-
signale.info('Checking out orphan branch %s', branch);
67+
const gitCheckout = async (pushDir: string, branchName: string) => {
68+
signale.info('Checking out orphan branch %s', branchName);
6669

67-
await execAsync(`git -C ${pushDir} checkout --orphan "${branch}"`);
70+
await execAsync(`git -C ${pushDir} checkout --orphan "${branchName}"`);
6871
};
6972

7073
const config = async (pushDir: string): Promise<boolean> => {
@@ -89,11 +92,36 @@ const commit = async (pushDir: string): Promise<boolean> => {
8992
return true;
9093
};
9194

92-
const push = async (pushDir: string, branch: string, context: Context) => {
93-
signale.info('Pushing to %s@%s', getRepository(context), branch);
95+
const push = async (pushDir: string, tagName: string, branchName: string, context: Context): Promise<boolean> => {
96+
signale.info('Pushing to %s@%s (tag: %s)', getRepository(context), branchName, tagName);
9497

9598
const url = getGitUrl(context);
96-
await execAsync(`git -C ${pushDir} push --quiet "${url}" "${branch}":"refs/heads/${branch}"`, true, 'git push');
99+
await execAsync(`git -C ${pushDir} push --delete origin tag ${tagName}`);
100+
await execAsync(`git -C ${pushDir} tag -l | xargs git -C ${pushDir} tag -d`);
101+
await execAsync(`git -C ${pushDir} fetch origin --tags`);
102+
await execAsync(`git -C ${pushDir} tag ${tagName}`);
103+
await execAsync(`git -C ${pushDir} push --quiet --tags "${url}" "${branchName}":"refs/heads/${branchName}"`, true, 'git push');
104+
return true;
105+
};
106+
107+
const updateRelease = async (tagName: string, octokit: GitHub, context: Context): Promise<boolean> => {
108+
const releases = await octokit.repos.listReleases({
109+
owner: context.repo.owner,
110+
repo: context.repo.repo,
111+
});
112+
const release = releases.data.find(release => release.tag_name === tagName);
113+
if (!release) {
114+
signale.warn('There is no release that has tag name: %s', tagName);
115+
return false;
116+
}
117+
118+
await octokit.repos.updateRelease({
119+
owner: context.repo.owner,
120+
repo: context.repo.repo,
121+
release_id: release.id,
122+
draft: false,
123+
});
124+
return true;
97125
};
98126

99127
const cloneForBuild = async (buildDir: string, context: Context) => {
@@ -127,8 +155,8 @@ const checkDiff = async (pushDir: string): Promise<boolean> => {
127155
};
128156

129157
const execAsync = (command: string, quiet: boolean = false, altCommand: string | null = null, suppressError: boolean = false) => new Promise<string>((resolve, reject) => {
130-
if ('string' === typeof altCommand) signale.info(`Run command: ${altCommand}`);
131-
else if (!quiet) signale.info(`Run command: ${command}`);
158+
if ('string' === typeof altCommand) signale.info('Run command: %s', altCommand);
159+
else if (!quiet) signale.info('Run command: %s', command);
132160
exec(command + (quiet ? ' > /dev/null 2>&1' : '') + (suppressError ? ' || :' : ''), (error, stdout) => {
133161
if (error) {
134162
if ('string' === typeof altCommand && !quiet) reject(new Error(`command [${altCommand}] exited with code ${error.code}. message: ${error.message}`));

src/utils/misc.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,15 @@ import path from 'path';
33
import yaml from 'js-yaml';
44
import {getInput} from '@actions/core' ;
55
import {Context} from '@actions/github/lib/context';
6-
import {TARGET_EVENT_NAME, TARGET_EVENT_ACTION, DEFAULT_COMMIT_MESSAGE, DEFAULT_COMMIT_NAME, DEFAULT_COMMIT_EMAIL, SEARCH_BUILD_COMMAND_TARGETS} from '../constant';
6+
import {
7+
TARGET_EVENT_NAME,
8+
TARGET_EVENT_ACTION,
9+
DEFAULT_COMMIT_MESSAGE,
10+
DEFAULT_COMMIT_NAME,
11+
DEFAULT_COMMIT_EMAIL,
12+
SEARCH_BUILD_COMMAND_TARGETS,
13+
DEFAULT_BRANCH_NAME,
14+
} from '../constant';
715

816
export const isTargetEvent = (context: Context): boolean => TARGET_EVENT_NAME === context.eventName && TARGET_EVENT_ACTION === context.payload.action;
917

@@ -51,6 +59,8 @@ export const getCommitName = (): string => getInput('COMMIT_NAME') || DEFAULT_CO
5159

5260
export const getCommitEmail = (): string => getInput('COMMIT_EMAIL') || DEFAULT_COMMIT_EMAIL;
5361

62+
export const getBranchName = (): string => getInput('BRANCH_NAME') || DEFAULT_BRANCH_NAME;
63+
5464
export const getWorkspace = (): string => process.env.GITHUB_WORKSPACE || '';
5565

5666
export const detectBuildCommand = (dir: string): boolean | string => {

0 commit comments

Comments
 (0)