diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..8ac1b52 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,58 @@ +name: JavaScript Build + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + type: choice + options: + - info + - warning + - debug + pull_request: + branches: + - "**" + paths: + - "Source/**" + - ".github/workflows/**" + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: 23.x + registry-url: "https://registry.npmjs.org" + + - uses: actions/cache@v4 + id: yarn-cache + with: + path: | + .yarn/cache + **/node_modules + **/.eslintcache + **/yarn.lock + key: ${{ runner.os }}-yarn-${{ hashFiles('**/package.json') }} + + - name: Yarn install + run: yarn + + - name: Build JS/TS + run: | + export NODE_OPTIONS="--max-old-space-size=4096" + yarn ci diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..ac3a273 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,118 @@ +name: Publish + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + workflow_dispatch: + inputs: + version: + description: 'Version to release' + required: true + default: '0.0.0' + type: string + release-notes: + description: 'Release notes' + required: true + default: 'No release notes' + type: string + logLevel: + description: 'Log level' + required: true + default: 'warning' + type: choice + options: + - info + - warning + - debug + pull_request: + types: [closed] + branches: + - "**" + paths: + - "Source/**" + +permissions: + contents: write + +jobs: + release: + runs-on: ubuntu-latest + outputs: + version: ${{ steps.release.outputs.version }} + publish: ${{ steps.release.outputs.should-publish }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Release + id: release + uses: cratis/release-action@v1 + with: + version: ${{ github.event.inputs.version }} + release-notes: ${{ github.event.inputs.release-notes }} + + publish-npm-packages: + if: needs.release.outputs.publish == 'true' + runs-on: ubuntu-latest + needs: [release] + permissions: + contents: read + id-token: write + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: 23.x + registry-url: 'https://registry.npmjs.org' + + - name: Configure npm for OIDC-based publishing + run: | + # setup-node writes a placeholder _authToken (XXXXX-XXXXX-XXXXX-XXXXX) into + # .npmrc and exports NODE_AUTH_TOKEN with the same placeholder. npm uses this + # token as-is for registry auth → 404. Remove it so npm falls back to OIDC. + sed -i '/_authToken/d' "$NPM_CONFIG_USERCONFIG" + echo "NODE_AUTH_TOKEN=" >> "$GITHUB_ENV" + echo "--- .npmrc after stripping placeholder ---" + cat "$NPM_CONFIG_USERCONFIG" + + - name: Upgrade npm for trusted publishing (requires >= 11.5.1) + run: | + npm install -g npm@11 + NPM_VER="$(npm --version)" + echo "Installed npm $NPM_VER" + node -e " + const v = '$NPM_VER'.split('.').map(Number); + if (v[0] < 11 || (v[0] === 11 && v[1] < 5) || (v[0] === 11 && v[1] === 5 && v[2] < 1)) { + console.error('npm >= 11.5.1 is required for trusted publishing, got $NPM_VER'); + process.exit(1); + } + " + + - uses: actions/cache@v4 + id: yarn-cache + with: + path: | + .yarn/cache + **/node_modules + **/.eslintcache + **/yarn.lock + key: ${{ runner.os }}-yarn-${{ hashFiles('**/package.json') }} + + - name: Yarn install + run: yarn + + - name: Publish NPM packages + run: | + yarn build + yarn publish-version ${{ needs.release.outputs.version }} + + - name: Git reset (package.json files changed) + run: | + git reset --hard diff --git a/Source/package.json b/Source/package.json index 13bc911..63aff23 100644 --- a/Source/package.json +++ b/Source/package.json @@ -6,8 +6,12 @@ "license": "MIT", "repository": { "type": "git", - "url": "git+https://github.com/einari/Chronicle.TypeScript.git" + "url": "git+https://github.com/Cratis/Chronicle.TypeScript.git" }, + "files": [ + "dist", + "**/*.ts" + ], "publishConfig": { "access": "public" }, diff --git a/package.json b/package.json index 40147b3..6f7268f 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,8 @@ "scripts": { "compile": "yarn workspaces foreach -A -t run compile", "build": "yarn workspaces foreach -A -t run build", - "clean": "yarn workspaces foreach -A -t run clean" + "clean": "yarn workspaces foreach -A -t run clean", + "ci": "yarn clean && yarn build", + "publish-version": "node ./publish-version.js" } } diff --git a/publish-version.js b/publish-version.js new file mode 100644 index 0000000..bc5ec86 --- /dev/null +++ b/publish-version.js @@ -0,0 +1,48 @@ +#!/usr/bin/env node + +if (process.argv.length < 3) { + console.log('You have to specify a version'); + console.log('\nUsage: node publish-version.js '); + process.exit(1); +} + +const fs = require('fs'); +const path = require('path'); +const { spawnSync } = require('child_process'); + +const version = process.argv[2]; +const sourceDir = path.join(__dirname, 'Source'); +const packageJsonPath = path.join(sourceDir, 'package.json'); + +// Read and update version in Source/package.json +const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); +if (packageJson.private === true) { + console.log(`Skipping private package '${packageJson.name}'`); + process.exit(0); +} + +packageJson.version = version; +fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 4) + '\n'); +console.log(`Set version of '${packageJson.name}' to ${version}`); + +// Copy README.md to Source if it doesn't exist there +const sourceReadme = path.join(sourceDir, 'README.md'); +if (!fs.existsSync(sourceReadme)) { + const rootReadme = path.join(__dirname, 'README.md'); + if (fs.existsSync(rootReadme)) { + fs.copyFileSync(rootReadme, sourceReadme); + console.log('Copied README.md to Source/'); + } +} + +// Publish to npm +console.log(`Publishing '${packageJson.name}' at version ${version}`); +const result = spawnSync('npm', ['publish', '--provenance'], { + cwd: sourceDir, + stdio: 'inherit' +}); + +if (result.status !== 0) { + console.error(`Failed to publish '${packageJson.name}'`); + process.exit(result.status || 1); +}