chore: versioning

This commit is contained in:
2026-05-26 17:10:26 +02:00
parent 51d738a442
commit 0fd3a41f1c
5 changed files with 114 additions and 71 deletions
+6 -48
View File
@@ -6,6 +6,10 @@ on:
permissions: permissions:
contents: write contents: write
env:
VERSION_MAJOR: '1'
VERSION_MINOR: '1'
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -17,10 +21,10 @@ jobs:
fetch-depth: 0 fetch-depth: 0
fetch-tags: true fetch-tags: true
- name: Use NodeJS v24.14.0 - name: Use NodeJS v22.22.3
uses: actions/setup-node@v6 uses: actions/setup-node@v6
with: with:
node-version: '24.14.0' node-version: '22.22.3'
registry-url: 'https://registry.npmjs.org' registry-url: 'https://registry.npmjs.org'
package-manager-cache: false package-manager-cache: false
@@ -39,49 +43,3 @@ jobs:
- name: Run Build - name: Run Build
run: npm run build run: npm run build
- name: Publish Library
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Create GitHub release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_TAG: v${{ steps.release_version.outputs.tag }}
run: |
git fetch --force --tags
previous_tag="$(gh api repos/${{ github.repository }}/releases --paginate --jq '.[] | select(.draft == false) | .tag_name' | grep -Fxv "$RELEASE_TAG" | head -n 1 || true)"
if [ -n "$previous_tag" ]; then
if git rev-parse --verify --quiet "${previous_tag}^{commit}" >/dev/null; then
commit_messages="$(git log --reverse --format='- %s' "${previous_tag}..${GITHUB_SHA}")"
else
commit_messages="$(git log --reverse --format='- %s' "${GITHUB_SHA}")"
fi
full_changelog="https://github.com/${{ github.repository }}/compare/${previous_tag}...${RELEASE_TAG}"
else
commit_messages="$(git log --reverse --format='- %s' "${GITHUB_SHA}")"
full_changelog=""
fi
if [ -z "$commit_messages" ]; then
commit_messages='- No commits since the previous release'
fi
{
echo '## Changes'
echo
printf '%s\n' "$commit_messages"
echo
if [ -n "$full_changelog" ]; then
echo "**Full Changelog**: ${full_changelog}"
fi
} > release-notes.md
if gh release view "$RELEASE_TAG" >/dev/null 2>&1; then
gh release edit "$RELEASE_TAG" --title "$RELEASE_TAG" --notes-file release-notes.md
else
gh release create "$RELEASE_TAG" --target "${GITHUB_SHA}" --title "$RELEASE_TAG" --notes-file release-notes.md
fi
+2 -2
View File
@@ -15,10 +15,10 @@ jobs:
- name: Checkout Repository - name: Checkout Repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: use NodeJS v24.14.0 - name: use NodeJS v22.22.3
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: '24.14.0' node-version: '22.22.3'
- name: Install Dependencies - name: Install Dependencies
run: npm ci run: npm ci
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "discord-audio-stream", "name": "discord-audio-stream",
"version": "1.0.DDDhhmm", "version": "x.x.x",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "discord-audio-stream", "name": "discord-audio-stream",
"version": "1.0.DDDhhmm", "version": "x.x.x",
"license": "LGPL-2.1-only", "license": "LGPL-2.1-only",
"devDependencies": { "devDependencies": {
"@jest/globals": "^30.4.1", "@jest/globals": "^30.4.1",
+9 -6
View File
@@ -1,7 +1,7 @@
{ {
"name": "discord-audio-stream", "name": "discord-audio-stream",
"version": "1.0.DDDhhmm", "version": "x.x.x",
"license": "LGPL-2.1-only", "license": "LGPL-3.0-only",
"description": "A small Discord voice audio streaming library with managed ffmpeg playback.", "description": "A small Discord voice audio streaming library with managed ffmpeg playback.",
"exports": { "exports": {
".": { ".": {
@@ -26,7 +26,9 @@
}, },
"scripts": { "scripts": {
"update:dependencies": "npx npm-check-updates --upgrade", "update:dependencies": "npx npm-check-updates --upgrade",
"release:version": "node set-version.js", "release:version": "node set-version.js set-ci-version",
"check:version": "node set-version.js check-placeholder",
"fix:version": "node set-version.js fix-placeholder",
"lint": "eslint . --ext .ts,.tsx,.js,.cjs,.mjs", "lint": "eslint . --ext .ts,.tsx,.js,.cjs,.mjs",
"lint:fix": "eslint . --ext .ts,.tsx,.js,.cjs,.mjs --fix", "lint:fix": "eslint . --ext .ts,.tsx,.js,.cjs,.mjs --fix",
"lint:types": "eslint . --config eslint.config.typeaware.cjs --ext .ts,.tsx", "lint:types": "eslint . --config eslint.config.typeaware.cjs --ext .ts,.tsx",
@@ -34,7 +36,8 @@
"format:check": "prettier --check .", "format:check": "prettier --check .",
"typecheck": "tsc --noEmit", "typecheck": "tsc --noEmit",
"test": "jest --runInBand", "test": "jest --runInBand",
"check": "npm run format:check && npm run lint && npm run lint:types && npm run typecheck && npm run test", "check": "npm run check:version && npm run format:check && npm run lint && npm run lint:types && npm run typecheck && npm run test",
"fix": "npm run fix:version && npm run format && npm run lint:fix",
"build": "del-cli dist && tsup && tsc -p tsconfig.build.json && node scripts/copy-dts.cjs", "build": "del-cli dist && tsup && tsc -p tsconfig.build.json && node scripts/copy-dts.cjs",
"prepare": "husky" "prepare": "husky"
}, },
@@ -53,7 +56,7 @@
"24/7" "24/7"
], ],
"contributors": [ "contributors": [
"FrauJulian - Lechner Julian <fraujulian@lechner.top>" "Julian Lechner - FrauJulian <fraujulian@lechner.top>"
], ],
"lint-staged": { "lint-staged": {
"*.{ts,tsx,js,cjs,mjs}": [ "*.{ts,tsx,js,cjs,mjs}": [
@@ -103,7 +106,7 @@
} }
}, },
"engines": { "engines": {
"node": ">=22.12.0" "node": ">=22.22.3"
}, },
"private": false, "private": false,
"publishConfig": { "publishConfig": {
+95 -13
View File
@@ -1,21 +1,103 @@
const fs = require('fs'); const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8').toString()); const lockFilePath = 'package-lock.json';
const packageFilePath = 'package.json';
const placeholderVersion = 'x.x.x';
const command = process.argv[2];
const [major, minor] = pkg.version.split('.'); function readJson(path) {
const prefix = `${major}.${minor}.`; return JSON.parse(fs.readFileSync(path, 'utf8').toString());
}
const now = new Date(); function writeJson(path, value, spaces) {
const start = new Date(now.getFullYear(), 0, 0); fs.writeFileSync(path, `${JSON.stringify(value, null, spaces)}\n`);
const diff = now - start; }
const dayOfYear = Math.floor(diff / (1000 * 60 * 60 * 24));
const hh = String(now.getHours()).padStart(2, '0'); function getLockFile() {
const mm = String(now.getMinutes()).padStart(2, '0'); if (!fs.existsSync(lockFilePath)) {
return null;
}
const newVersion = `${prefix}${String(dayOfYear).padStart(3, '0')}${hh}${mm}`; return readJson(lockFilePath);
}
pkg.version = newVersion; function writeVersions(version) {
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2)); const pkg = readJson(packageFilePath);
pkg.version = version;
writeJson(packageFilePath, pkg, 2);
console.log('Version set to: ', newVersion); const lock = getLockFile();
if (lock) {
lock.version = version;
if (lock.packages?.['']) {
lock.packages[''].version = version;
}
writeJson(lockFilePath, lock, 4);
}
}
function checkPlaceholder() {
const pkg = readJson(packageFilePath);
const lock = getLockFile();
const errors = [];
if (pkg.version !== placeholderVersion) {
errors.push(`package.json version must be "${placeholderVersion}", got "${pkg.version}"`);
}
if (lock && lock.version !== placeholderVersion) {
errors.push(`package-lock.json version must be "${placeholderVersion}", got "${lock.version}"`);
}
if (lock?.packages?.[''] && lock.packages[''].version !== placeholderVersion) {
errors.push(
`package-lock.json packages[""] version must be "${placeholderVersion}", got "${lock.packages[''].version}"`,
);
}
if (errors.length > 0) {
for (const error of errors) {
console.error(error);
}
process.exit(1);
}
console.log(`Version placeholder validated: ${placeholderVersion}`);
}
function fixPlaceholder() {
writeVersions(placeholderVersion);
console.log(`Version placeholder set to: ${placeholderVersion}`);
}
function getCiVersion() {
const major = process.env.VERSION_MAJOR;
const minor = process.env.VERSION_MINOR;
const patch = process.env.VERSION_PATCH ?? process.env.GITHUB_RUN_NUMBER;
const segments = { major, minor, patch };
for (const [name, value] of Object.entries(segments)) {
if (!/^\d+$/.test(value ?? '')) {
console.error(`Missing or invalid ${name} version segment: "${value ?? ''}"`);
process.exit(1);
}
}
return `${major}.${minor}.${patch}`;
}
if (command === 'check-placeholder') {
checkPlaceholder();
} else if (command === 'fix-placeholder') {
fixPlaceholder();
} else if (command === 'set-ci-version') {
const ciVersion = getCiVersion();
writeVersions(ciVersion);
console.log(`CI version set to: ${ciVersion}`);
} else {
console.error('Invalid command. Use one of: check-placeholder, fix-placeholder, set-ci-version');
process.exit(1);
}