Skip to content

Commit 55160f2

Browse files
committed
Add the release mechanism, mirroring xslint
A tag-triggered release.yml publishes to npm via OIDC trusted publishing (with provenance) and sets the GitHub release notes from CHANGELOG.md, exactly as in xslint: @rultor release validates the tag and runs lint + test + coverage, then pushes the tag that triggers this workflow. Adds scripts/changelog-notes.js, CHANGELOG.md with the 0.0.1 notes, and the repository field npm provenance needs. Version stays 0.0.0 and is stamped from the tag at release time.
1 parent 33d3d9f commit 55160f2

4 files changed

Lines changed: 95 additions & 0 deletions

File tree

.github/workflows/release.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 Max Trunnikov
2+
# SPDX-License-Identifier: MIT
3+
---
4+
name: release
5+
'on':
6+
push:
7+
tags:
8+
- '[0-9]+.[0-9]+.[0-9]+'
9+
permissions:
10+
contents: write
11+
id-token: write
12+
concurrency:
13+
group: release-${{ github.ref }}
14+
cancel-in-progress: false
15+
jobs:
16+
release:
17+
runs-on: ubuntu-24.04
18+
steps:
19+
- uses: actions/checkout@v4
20+
- uses: actions/setup-node@v4
21+
with:
22+
node-version: 22
23+
registry-url: https://registry.npmjs.org
24+
- run: npm install
25+
- name: Stamp the released version
26+
env:
27+
VERSION: ${{ github.ref_name }}
28+
run: sed -i "s/\"version\": \"0\.0\.0\"/\"version\": \"${VERSION}\"/" package.json
29+
- run: npm run lint
30+
- run: npm test
31+
- run: npm run coverage
32+
- name: Publish to npm via OIDC
33+
run: |
34+
npm install -g npm@latest
35+
npm publish --provenance --access public
36+
- name: Set the GitHub release notes from the changelog
37+
env:
38+
GH_TOKEN: ${{ github.token }}
39+
VERSION: ${{ github.ref_name }}
40+
run: |
41+
node scripts/changelog-notes.js "${VERSION}" > notes.md
42+
gh release edit "${VERSION}" --notes-file notes.md \
43+
|| gh release create "${VERSION}" --title "${VERSION}" \
44+
--notes-file notes.md

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Changelog
2+
3+
All notable changes to this project are documented in this file. The format is
4+
based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the
5+
project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6+
7+
## Unreleased
8+
9+
## 0.0.1
10+
11+
- Initial release. A Language Server Protocol server that wraps
12+
[xslint](https://github.com/maxonfjvipon/xslint): live diagnostics as you
13+
type over the editor buffer, quick-fixes for the fixable checks, and a
14+
fix-all action — all reusing xslint's own `lint` and `fixed` engine, so an
15+
editor fix is identical to a command-line `--fix`. Ships with a VS Code
16+
extension client, and works in any LSP-capable editor.

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
"description": "Language Server Protocol server for xslint",
55
"license": "MIT",
66
"author": "Max Trunnikov",
7+
"repository": {
8+
"type": "git",
9+
"url": "git+https://github.com/maxonfjvipon/xslint-lsp.git"
10+
},
711
"type": "commonjs",
812
"main": "src/server.js",
913
"bin": {

scripts/changelog-notes.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* SPDX-FileCopyrightText: Copyright (c) 2025-2026 Max Trunnikov
3+
* SPDX-License-Identifier: MIT
4+
*/
5+
6+
'use strict'
7+
8+
const fs = require('fs')
9+
10+
const version = process.argv[2]
11+
if (!version) {
12+
throw new Error('usage: changelog-notes.js <version>')
13+
}
14+
15+
const lines = fs.readFileSync('CHANGELOG.md', 'utf-8').split('\n')
16+
const start = lines.findIndex(
17+
(line) => line === `## ${version}` || line.startsWith(`## ${version} `),
18+
)
19+
if (start < 0) {
20+
throw new Error(`no "## ${version}" section in CHANGELOG.md`)
21+
}
22+
const next = lines.findIndex(
23+
(line, index) => index > start && line.startsWith('## '),
24+
)
25+
const stop = next < 0 ? lines.length : next
26+
const notes = lines.slice(start + 1, stop).join('\n').trim()
27+
if (notes === '') {
28+
throw new Error(`the "## ${version}" section is empty`)
29+
}
30+
31+
process.stdout.write(`${notes}\n`)

0 commit comments

Comments
 (0)