Skip to content

Commit 6842da1

Browse files
authored
feat(github-action): a simple-release api for github action (#95)
1 parent b459f54 commit 6842da1

File tree

19 files changed

+755
-37
lines changed

19 files changed

+755
-37
lines changed

.github/workflows/comment.yml

Lines changed: 0 additions & 33 deletions
This file was deleted.

.github/workflows/release.yml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
name: Release
2+
on:
3+
issue_comment:
4+
types: [created, deleted]
5+
push:
6+
branches:
7+
- action
8+
jobs:
9+
check:
10+
runs-on: ubuntu-latest
11+
name: Check if release job should run
12+
outputs:
13+
continue: ${{ steps.check.outputs.continue }}
14+
steps:
15+
- name: Check context
16+
id: check
17+
uses: actions/github-script@v7
18+
with:
19+
script: |
20+
function ifSetOptionsComment() {
21+
const {
22+
eventName,
23+
payload: {
24+
issue,
25+
comment
26+
}
27+
} = context
28+
const isPullRequest = issue?.pull_request
29+
const issueAuthor = issue?.user?.login
30+
const issueBody = issue?.body
31+
const issueState = issue?.state
32+
const commentBody = comment?.body
33+
34+
if (eventName === 'issue_comment') {
35+
if (isPullRequest
36+
&& issueAuthor === 'github-actions[bot]'
37+
&& issueState === 'open'
38+
&& issueBody?.includes('simple-release-pull-request: true')
39+
&& commentBody?.includes('!simple-release/set-options')
40+
) {
41+
const matches = issueBody.match(/simple-release-branch-to:\s*([^\s]+)/)
42+
43+
if (matches) {
44+
return matches[1]
45+
}
46+
}
47+
48+
return false // not a pull request comment, stop action
49+
}
50+
51+
return null // continue
52+
}
53+
54+
core.setOutput('continue', ifSetOptionsComment() !== false)
55+
release:
56+
runs-on: ubuntu-latest
57+
name: Release
58+
needs: check
59+
if: needs.check.outputs.continue == 'true'
60+
steps:
61+
- name: Checkout the repository
62+
uses: actions/checkout@v4
63+
- name: Install pnpm
64+
uses: pnpm/action-setup@v2
65+
with:
66+
version: 10
67+
- name: Install Node.js
68+
uses: actions/setup-node@v4
69+
with:
70+
node-version: 18
71+
cache: 'pnpm'
72+
- name: Install dependencies
73+
run: pnpm install
74+
- name: Simple release
75+
run: pnpm tsm --no-warnings ./packages/ci/src/action.ts
76+
env:
77+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.simple-release.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { PnpmWorkspacesProject } from './packages/pnpm/src/index.js'
2+
3+
export const project = new PnpmWorkspacesProject({
4+
mode: 'fixed'
5+
})
6+
7+
export const releaser = {
8+
verbose: true,
9+
dryRun: true
10+
}

packages/ci/.eslintrc.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"extends": [
3+
"@trigen/eslint-config/typescript",
4+
"@trigen/eslint-config/typescript-requiring-type-checking",
5+
"@trigen/eslint-config/jest"
6+
],
7+
"parserOptions": {
8+
"tsconfigRootDir": "./packages/ci",
9+
"project": ["./tsconfig.json"]
10+
}
11+
}

packages/ci/package.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "ci",
3+
"type": "module",
4+
"private": true,
5+
"version": "0.0.0",
6+
"description": "A ci utilities.",
7+
"author": {
8+
"name": "Dan Onoshko",
9+
"email": "[email protected]",
10+
"url": "https://github.com/dangreen"
11+
},
12+
"license": "MIT",
13+
"homepage": "https://github.com/TrigenSoftware/simple-release/tree/master/packages/ci#readme",
14+
"funding": "https://ko-fi.com/dangreen",
15+
"repository": {
16+
"type": "git",
17+
"url": "https://github.com/TrigenSoftware/simple-release.git",
18+
"directory": "packages/ci"
19+
},
20+
"bugs": {
21+
"url": "https://github.com/TrigenSoftware/simple-release/issues"
22+
},
23+
"keywords": [],
24+
"engines": {
25+
"node": ">=18"
26+
},
27+
"scripts": {
28+
"lint": "eslint --parser-options tsconfigRootDir:. '**/*.{js,ts}'",
29+
"test:types": "tsc --noEmit",
30+
"test": "run -p lint test:types"
31+
},
32+
"dependencies": {
33+
"@actions/github": "^6.0.1",
34+
"@simple-release/config": "workspace:^",
35+
"@simple-release/github-action": "workspace:^"
36+
}
37+
}

packages/ci/src/action.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { getOctokit } from '@actions/github'
2+
import { load } from '@simple-release/config'
3+
import { ReleaserGithubAction } from '@simple-release/github-action'
4+
5+
const {
6+
project,
7+
releaser,
8+
...options
9+
} = await load({
10+
config: true,
11+
project: true
12+
})
13+
14+
await new ReleaserGithubAction({
15+
project,
16+
octokit: getOctokit(process.env.GITHUB_TOKEN!),
17+
...releaser
18+
})
19+
.setOptions(options)
20+
.runAction()

packages/ci/tsconfig.build.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"extends": "../../tsconfig.json",
3+
"compilerOptions": {
4+
"outDir": "dist"
5+
},
6+
"include": [
7+
"src"
8+
],
9+
"exclude": [
10+
"**/*.spec.ts"
11+
]
12+
}

packages/ci/tsconfig.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"extends": "./tsconfig.build.json",
3+
"include": [
4+
"src"
5+
],
6+
"exclude": []
7+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"extends": [
3+
"@trigen/eslint-config/typescript",
4+
"@trigen/eslint-config/typescript-requiring-type-checking",
5+
"@trigen/eslint-config/jest"
6+
],
7+
"parserOptions": {
8+
"tsconfigRootDir": "./packages/github-action",
9+
"project": ["./tsconfig.json"]
10+
},
11+
"rules": {
12+
"@typescript-eslint/naming-convention": "off"
13+
}
14+
}

packages/github-action/README.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# @simple-release/github-action
2+
3+
[![ESM-only package][package]][package-url]
4+
[![NPM version][npm]][npm-url]
5+
[![Node version][node]][node-url]
6+
[![Dependencies status][deps]][deps-url]
7+
[![Install size][size]][size-url]
8+
[![Build status][build]][build-url]
9+
[![Coverage status][coverage]][coverage-url]
10+
11+
[package]: https://img.shields.io/badge/package-ESM--only-ffe536.svg
12+
[package-url]: https://nodejs.org/api/esm.html
13+
14+
[npm]: https://img.shields.io/npm/v/@simple-release/github-action.svg
15+
[npm-url]: https://www.npmjs.com/package/@simple-release/github-action
16+
17+
[node]: https://img.shields.io/node/v/@simple-release/github-action.svg
18+
[node-url]: https://nodejs.org
19+
20+
[deps]: https://img.shields.io/librariesio/release/npm/@simple-release/github-action
21+
[deps-url]: https://libraries.io/npm/@simple-release%2Fgithub-actions/tree
22+
23+
[size]: https://packagephobia.com/badge?p=@simple-release/github-action
24+
[size-url]: https://packagephobia.com/result?p=@simple-release/github-action
25+
26+
[build]: https://img.shields.io/github/actions/workflow/status/TrigenSoftware/simple-release/tests.yml?branch=main
27+
[build-url]: https://github.com/TrigenSoftware/simple-release/actions
28+
29+
[coverage]: https://coveralls.io/repos/github/TrigenSoftware/simple-release/badge.svg?branch=main
30+
[coverage-url]: https://coveralls.io/github/TrigenSoftware/simple-release?branch=main
31+
32+
A simple-release api for github action.
33+
34+
## Install
35+
36+
```bash
37+
# pnpm
38+
pnpm add @simple-release/github-action
39+
# yarn
40+
yarn add @simple-release/github-action
41+
# npm
42+
npm i @simple-release/github-action
43+
```
44+
45+
## Usage
46+
47+
```js
48+
import { getOctokit } from '@actions/github'
49+
import { load } from '@simple-release/config'
50+
import { ReleaserGithubAction, ifReleaseCommit } from '@simple-release/github-action'
51+
52+
const {
53+
project,
54+
releaser,
55+
...options
56+
} = await load({
57+
config: true,
58+
project: true
59+
})
60+
const action = await new ReleaserGithubAction({
61+
project,
62+
octokit: getOctokit(token),
63+
...releaser
64+
})
65+
66+
// Create pull request with version bump
67+
action
68+
.setOptions(options)
69+
.checkout()
70+
.fetchOptions()
71+
.bump()
72+
.commit()
73+
.push()
74+
.pullRequest()
75+
.run()
76+
77+
// Publish release and project
78+
action
79+
.setOptions(options)
80+
.tag()
81+
.push()
82+
.release()
83+
.publish()
84+
.run(ifReleaseCommit)
85+
86+
// Run all steps to create a pull request with version bump
87+
action
88+
.setOptions(options)
89+
.runPullRequestAction()
90+
91+
// Run all steps to release project
92+
action
93+
.setOptions(options)
94+
.runReleaseAction()
95+
96+
// Detect action by commit type and run appropriate steps
97+
action
98+
.setOptions(options)
99+
.runAction()
100+
```
101+
102+
### fethchOptions
103+
104+
You can pass additional options to releaser via comment in your pull request. Your comment should start with `!simple-release/set-options` and contain JSON object with options. For example:
105+
106+
````
107+
!simple-release/set-options
108+
109+
```json
110+
{
111+
"bump": {
112+
"prerelease": "alpha"
113+
}
114+
}
115+
```
116+
````
117+
118+
To fetch and parse comments you should use `fetchOptions` step after `checkout` step.

0 commit comments

Comments
 (0)