Skip to content

Commit

Permalink
feat: init (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
atian25 authored Dec 14, 2022
1 parent e674998 commit 5fe72d7
Show file tree
Hide file tree
Showing 9 changed files with 375 additions and 2 deletions.
73 changes: 73 additions & 0 deletions .github/workflows/node-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: Node.js Release

on:
workflow_call:
inputs:
checkTest:
type: boolean
description: 'whether run test before release'
default: true
dryRun:
type: boolean
description: 'pass dry-run to semantic-release'
default: false

jobs:
Release:
runs-on: ubuntu-latest
defaults:
run:
working-directory: main_repo

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

steps:
# Checkout action repository
- name: Checkout action repository
uses: actions/checkout@v3
with:
repository: artusjs/github-actions
path: action_repo
# ref: impl

# Checkout project repository
- name: Checkout project repository
uses: actions/checkout@v3
with:
path: main_repo

# Setup Node.js environment
- name: Setup Node.js
uses: actions/setup-node@v3

# Install action dependencies
- name: Install action dependencies
run: npm i --no-package-lock --no-fund --omit=dev
working-directory: action_repo/scripts/release

#Install dependencies
- name: Install dependencies
run: npm i --no-package-lock --no-fund

# Run Test Only
- name: Run Test
run: npm test
if: inputs.checkTest

- name: Semantic Release
id: release
run: node ../action_repo/scripts/release/index.js
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DRYRUN: ${{ inputs.dryRun }}

- name: Publish ${{ steps.release.outputs.name }}@${{ steps.release.outputs.release_version }}
if: steps.release.outputs.release_version
run: |
echo ${{ steps.release.outputs.name }}
echo ${{ steps.release.outputs.release_version }}
echo ${{ steps.release.outputs.registry }}
85 changes: 85 additions & 0 deletions .github/workflows/node-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: Node.js Unit Test

on:
workflow_call:
inputs:
os:
type: string
description: 'Operator System, such as: ubuntu-latest,macos-latest'
default: 'ubuntu-latest, macos-latest, windows-latest'

version:
type: string
description: 'Node.js Version, such as 16, 18'
default: '16, 18'

jobs:
Setup:
runs-on: ubuntu-latest
outputs:
os: ${{ steps.handler.outputs.os }}
version: ${{ steps.handler.outputs.version }}

steps:
# Checkout action repository
- name: Checkout
uses: actions/checkout@v3
with:
repository: artusjs/github-actions
path: action_repo
# ref: impl

# Setup Node.js environment
- name: Setup Node.js
uses: actions/setup-node@v3

# Install dependencies
- name: Install dependencies
run: npm i --no-package-lock --no-fund --omit=dev
working-directory: action_repo/scripts/test

# Normalize inputs style
- name: Convert Inputs to Matrix
id: handler
run: node action_repo/scripts/test/index.js
env:
INPUT_OS: ${{ inputs.os }}
INPUT_VERSION: ${{ inputs.version }}

Test:
needs: Setup
strategy:
fail-fast: false
matrix:
os: ${{ fromJSON(needs.setup.outputs.os) }}
version: ${{ fromJSON(needs.setup.outputs.version) }}

name: Test (${{ matrix.os }}, ${{ matrix.version }})
runs-on: ${{ matrix.os }}

concurrency:
group: ${{ github.workflow }}-#${{ github.event.pull_request.number || github.ref }}-(${{ matrix.os }}, ${{ matrix.version }})
cancel-in-progress: true

steps:
- name: Checkout Git Source
uses: actions/checkout@v3

- name: Use Node.js ${{ matrix.version }}
uses: actions/setup-node@v3
with:
version: ${{ matrix.version }}

- name: Install Dependencies
run: npm i --no-package-lock --no-fund

- name: Run Lint
run: npm run lint

- name: Run Test
run: npm run ci

- name: Code Coverage
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules/
dist/
coverage/
*-lock*[.yaml, .json]
**/*.tgz
100 changes: 98 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,98 @@
# semantic-release-preset
https://semantic-release.gitbook.io/
# artusjs/github-actions

为开源项目提供常见的可复用的 [GitHub Actions Workflow](https://docs.github.com/en/actions/using-workflows/reusing-workflows#using-inputs-and-secrets-in-a-reusable-workflow)

## 单元测试

- 配置 `npm scripts`

```json
{
"name": "your-project",
"scripts": {
"lint": "eslint .",
"test": "mocha",
"ci": "c8 npm test"
},
}

- 创建 `.github/workflows/ci.yml`:

```yaml
name: CI

on:
push:
branches: [ master, main ]

pull_request:
branches: [ master, main, next, beta, "*.x" ]

schedule:
- cron: '0 2 * * *'

workflow_dispatch:

jobs:
Job:
name: Node.js
uses: artusjs/github-actions/.github/workflows/node-test.yml@master
# 支持以下自定义配置,一般用默认值即可
# with:
# os: 'ubuntu-latest, macos-latest, windows-latest'
# version: '16, 18'
```

## 发布 NPM 包

使用 [semantic-release](https://semantic-release.gitbook.io/) 自动发布 NPM 包。

### 发布流程

- 根据 Git 日志自动计算版本号
- 自动生成 ChangeLog 文件
- 自动创建 GitHub Release 说明
- 自动打打 Tag 标签
- 自动发布到 Registry,支持 NPM 和 GitHub,配置 `publishConfig.registry` 即可
- 支持合并到主干分支后自动发布,也支持手动发布

### 版本号规则

根据 Commit Message 自动计算下一个版本号:
- major 大版本:`BREAKING CHANGE`
- minor 特性版本: `feat:`
- patch 补丁版本:`fix:`
- 不发布: `chore:` / `docs:` / `style:`
- 详见:https://github.com/semantic-release/commit-analyzer

**注意:**
- master 首次发布将是 1.0.0 版本
- 如果你不期望直接发布,请在 beta 分支提交代码运行,将发布 `1.0.0-beta.1` 版本,同样符合 Semver 规则
- 不支持发布 0.x 版本


### 配置方式

创建 `.github/workflows/release.yml`

```yaml
name: Release
on:
# 合并后自动发布
push:
branches: [ master, main, next, beta, "*.x" ]

# 手动发布
workflow_dispatch:

jobs:
release:
name: Node.js
uses: artusjs/github-actions/.github/workflows/node-release.yml@master
# with:
# checkTest: false
# dryRun: true
```

> **手动发布方式**:访问仓库的 Actions 页面,左侧选择 Release Workflow,点击右侧的 `Run Workflow` 即可。
57 changes: 57 additions & 0 deletions scripts/release/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
const core = require('@actions/core');
const { getExecOutput } = require('@actions/exec');
const semanticRelease = require('semantic-release');

async function execGit(cmd) {
const { stdout } = await getExecOutput(cmd);
return stdout.trim();
}

async function run() {
const pkgInfo = require(`${process.cwd()}/package.json`);
const registry = pkgInfo.publishConfig?.registry || 'https://registry.npmjs.org';
core.setOutput('name', pkgInfo.name);
core.setOutput('registry', registry);

const lastCommitId = await execGit(`git log -n1 --format="%h"`);

try {
const result = await semanticRelease({
dryRun: process.env.DRYRUN === 'true',
});

const { nextRelease, lastRelease } = result;

if (!nextRelease) {
core.notice('No release need to be published.');
core.summary.addRaw('No release need to be published.');
await core.summary.write();
} else {
core.info(`Published release: ${nextRelease.version}`);
core.setOutput('release_version', nextRelease.version);

core.summary.addRaw(`## [${pkgInfo.name}](https://github.com/${process.env.GITHUB_REPOSITORY})\n`);
core.summary.addRaw(`- Release: ${lastRelease?.version ?? ''} -> ${nextRelease.version}\n`);
core.summary.addRaw(`- Registry: ${registry}\n`);
core.summary.addRaw(`- DryRun: ${process.env.DRYRUN}\n`);
core.summary.addRaw(nextRelease.notes);
await core.summary.write();
}
console.log('Result:', result);
} catch (error) {
console.error('> Rollback to last commit');
const currentCommitId = await execGit(`git log -n1 --format="%h"`);
const tagId = await execGit(`git tag --contains ${currentCommitId}`);

await execGit(`git push --delete origin ${tagId}`);
await execGit(`git reset --hard ${lastCommitId}`);
await execGit(`git push --force`);

console.error('> Rollback finished');

// console.error(error);
core.setFailed(error);
}
}

run();
12 changes: 12 additions & 0 deletions scripts/release/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "ci-release",
"dependencies": {
"@actions/core": "^1.10.0",
"@actions/exec": "^1.1.1",
"@semantic-release/changelog": "^6.0.2",
"@semantic-release/exec": "^6.0.3",
"@semantic-release/git": "^10.0.1",
"conventional-changelog-conventionalcommits": "^5.0.0",
"semantic-release": "^19.0.5"
}
}
30 changes: 30 additions & 0 deletions scripts/release/release.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module.exports = {
plugins: [
[ '@semantic-release/commit-analyzer', { preset: 'conventionalcommits' } ],
[ '@semantic-release/release-notes-generator', { preset: 'conventionalcommits' } ],
[ '@semantic-release/changelog', { changelogTitle: '# Changelog' } ],
[ '@semantic-release/npm', {} ],

// [ '@semantic-release/exec', {
// 'publishCmd': 'ls -l dist && ls -l .semantic-release && tar -ztvf .semantic-release/*.tgz',
// } ],

[ '@semantic-release/git',
{
message: 'Release <%= nextRelease.version %>\n\n[skip ci]\n\n<%= nextRelease.notes %>',
},
],

// [{
// fail: function (...args) {
// console.log('Hello World!', args);
// }
// }],

[ '@semantic-release/github',
{
addReleases: 'bottom',
},
],
],
};
9 changes: 9 additions & 0 deletions scripts/test/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const core = require('@actions/core');

const os = core.getInput('os').split(',').map(x => x.trim());
const version = core.getInput('version').split(',').map(x => x.trim());

core.setOutput('os', JSON.stringify(os));
core.setOutput('version', JSON.stringify(version));

core.info(`os: ${os}, version: ${version}`);
6 changes: 6 additions & 0 deletions scripts/test/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "ci-test",
"dependencies": {
"@actions/core": "^1.10.0"
}
}

0 comments on commit 5fe72d7

Please sign in to comment.