Skip to content

Commit f2f6479

Browse files
committed
ci: add release workflow for deno and npm
1 parent 0deb5af commit f2f6479

File tree

9 files changed

+402
-1
lines changed

9 files changed

+402
-1
lines changed

.github/workflows/release-npm.yaml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: release-npm
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
jobs:
8+
release:
9+
runs-on: ${{ matrix.os }}
10+
11+
strategy:
12+
matrix:
13+
os: [ubuntu-latest]
14+
deno: [v1.x]
15+
node: [16.x]
16+
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@v3
20+
21+
- uses: denoland/setup-deno@v1
22+
with:
23+
deno-version: ${{ matrix.deno }}
24+
25+
- name: Cache node_modules
26+
uses: actions/cache@v2
27+
with:
28+
path: ~/.pnpm-store
29+
key: ${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
30+
restore-keys: |
31+
${{ runner.os }}-
32+
33+
- uses: pnpm/[email protected]
34+
with:
35+
version: 7.16.0
36+
run_install: |
37+
- recursive: true
38+
args: [--frozen-lockfile, --prefer-offline, --ignore-scripts]
39+
40+
- name: Get tag version
41+
if: startsWith(github.ref, 'refs/tags/')
42+
id: get_tag_version
43+
run: echo ::set-output name=TAG_VERSION::${GITHUB_REF/refs\/tags\//}
44+
45+
- uses: actions/setup-node@v2
46+
with:
47+
node-version: ${{ matrix.node }}
48+
registry-url: 'https://registry.npmjs.org'
49+
50+
- name: build
51+
run: deno run -A ./_tools/build_npm.ts ${{steps.get_tag_version.outputs.TAG_VERSION}}
52+
53+
- name: publish
54+
env:
55+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
56+
run: deno run -A ./_tools/publish_npm.ts ${{steps.get_tag_version.outputs.TAG_VERSION}}
57+

.github/workflows/release.yaml

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
name: release
2+
3+
on:
4+
push:
5+
branches:
6+
- beta
7+
- main
8+
9+
jobs:
10+
lint:
11+
runs-on: ${{ matrix.os }}
12+
13+
strategy:
14+
matrix:
15+
os: [ubuntu-latest]
16+
deno: [v1.x]
17+
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v3
21+
22+
- uses: denoland/setup-deno@v1
23+
with:
24+
deno-version: ${{ matrix.deno }}
25+
26+
- name: Lint
27+
run: |
28+
deno fmt --check
29+
deno lint
30+
31+
test:
32+
runs-on: ${{ matrix.os }}
33+
34+
strategy:
35+
matrix:
36+
os: [ubuntu-latest]
37+
deno: [v1.x]
38+
39+
steps:
40+
- name: Checkout
41+
uses: actions/checkout@v3
42+
43+
- uses: denoland/setup-deno@v1
44+
with:
45+
deno-version: ${{ matrix.deno }}
46+
47+
- name: Test
48+
run: deno task test --coverage=coverage
49+
50+
- name: Generate coverage
51+
if: ${{ matrix.deno == 'v1.x' }}
52+
run: deno task coverage coverage --output=cov_profile.lcov --lcov
53+
54+
- uses: codecov/codecov-action@v3
55+
if: ${{ matrix.deno == 'v1.x' }}
56+
with:
57+
files: cov_profile.lcov
58+
59+
release:
60+
needs: [lint, test]
61+
runs-on: ${{ matrix.os }}
62+
63+
strategy:
64+
matrix:
65+
os: [ubuntu-latest]
66+
67+
steps:
68+
- name: Checkout
69+
uses: actions/checkout@v3
70+
with:
71+
token: ${{ secrets.GH_TOKEN }}
72+
73+
- uses: cycjimmy/semantic-release-action@v3
74+
with:
75+
extra_plugins: |
76+
@semantic-release/changelog
77+
@semantic-release/git
78+
env:
79+
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}

.releaserc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"branches": [
3+
"main",
4+
{
5+
"name": "beta",
6+
"prerelease": true
7+
}
8+
],
9+
"plugins": [
10+
"@semantic-release/commit-analyzer",
11+
"@semantic-release/release-notes-generator",
12+
"@semantic-release/changelog",
13+
"@semantic-release/github",
14+
[
15+
"@semantic-release/git",
16+
{
17+
"assets": [
18+
"CHANGELOG.md"
19+
],
20+
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
21+
}
22+
]
23+
],
24+
"tagFormat": "${version}"
25+
}

_tools/build_npm.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { build, emptyDir } from "https://deno.land/x/[email protected]/mod.ts";
2+
import { join } from "https://deno.land/[email protected]/path/mod.ts";
3+
import { makeOptions } from "./meta.ts";
4+
5+
async function buildPkg(version: string): Promise<void> {
6+
await emptyDir("./npm");
7+
const pkg = makeOptions(version);
8+
await Deno.copyFile("LICENSE", join(pkg.outDir, "LICENSE"));
9+
Deno.copyFile(
10+
join(".", "README.md"),
11+
join(pkg.outDir, "README.md"),
12+
);
13+
await build(pkg);
14+
}
15+
16+
if (import.meta.main) {
17+
const version = Deno.args[0];
18+
if (!version) {
19+
console.error("argument is required");
20+
Deno.exit(1);
21+
}
22+
await buildPkg(version);
23+
}

_tools/meta.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { BuildOptions } from "https://deno.land/x/[email protected]/mod.ts";
2+
3+
export const makeOptions = (version: string): BuildOptions => ({
4+
test: false,
5+
shims: {},
6+
compilerOptions: {
7+
lib: ["esnext", "dom"],
8+
},
9+
typeCheck: true,
10+
entryPoints: ["./mod.ts"],
11+
outDir: "./npm",
12+
package: {
13+
name: "@httpland/chain-handler",
14+
version,
15+
description:
16+
"Chainable and immutable HTTP handler for standard Request and Response",
17+
keywords: [
18+
"http",
19+
"handler",
20+
"chain",
21+
"chainable",
22+
"sequential",
23+
"request",
24+
"response",
25+
],
26+
license: "MIT",
27+
homepage: "https://github.com/httpland/chain-handler",
28+
repository: {
29+
type: "git",
30+
url: "git+https://github.com/httpland/chain-handler.git",
31+
},
32+
bugs: {
33+
url: "https://github.com/httpland/chain-handler/issues",
34+
},
35+
sideEffects: false,
36+
type: "module",
37+
publishConfig: {
38+
access: "public",
39+
},
40+
},
41+
packageManager: "pnpm",
42+
});

_tools/publish_npm.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { prerelease, valid } from "https://deno.land/x/[email protected]/mod.ts";
2+
import { makeOptions } from "./meta.ts";
3+
4+
if (import.meta.main) {
5+
const version = Deno.args[0];
6+
if (!version) {
7+
console.error("arg of version is required");
8+
Deno.exit(1);
9+
}
10+
if (!valid(version)) {
11+
console.error("The argument of version is invalid");
12+
Deno.exit(1);
13+
}
14+
15+
const isPrerelease = prerelease(version);
16+
const tag = isPrerelease?.[0] ?? "latest";
17+
18+
const pkg = makeOptions(version);
19+
const result = await Deno.run({
20+
cmd: ["npm", "publish", pkg.outDir, "--tag", String(tag)],
21+
stdout: "piped",
22+
})
23+
.output();
24+
25+
console.log(new TextDecoder().decode(result));
26+
}

deno.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"tasks": {
3+
"test": "deno test --import-map=./test_import_map.json --doc",
4+
"coverage": "deno coverage",
5+
"build:npm": "deno run -A _tools/build_npm.ts"
6+
},
7+
"fmt": {
8+
"files": {
9+
"exclude": ["CHANGELOG.md", "CODE_OF_CONDUCT.md"]
10+
}
11+
},
12+
"lint": {
13+
"files": {
14+
"exclude": ["CHANGELOG.md", "CODE_OF_CONDUCT.md"]
15+
}
16+
},
17+
"test": {
18+
"files": {
19+
"exclude": ["CHANGELOG.md", "CODE_OF_CONDUCT.md"]
20+
}
21+
},
22+
"compilerOptions": {
23+
"noImplicitReturns": true,
24+
"noImplicitOverride": true,
25+
"noUncheckedIndexedAccess": true
26+
}
27+
}

0 commit comments

Comments
 (0)