diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a7e4dd5..64945ee 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -18,12 +18,12 @@ jobs: steps: - name: Begin CI... - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Use Node ${{ env.NODE_VERSION }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: node-version: ${{ env.NODE_VERSION }} - - uses: actions/cache@v2 + - uses: actions/cache@v3 with: path: '**/node_modules' key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/yarn.lock') }} @@ -38,8 +38,8 @@ jobs: steps: - name: Begin CI... - uses: actions/checkout@v2 - - uses: actions/cache@v2 + uses: actions/checkout@v3 + - uses: actions/cache@v3 with: path: '**/node_modules' key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/yarn.lock') }} @@ -54,8 +54,8 @@ jobs: steps: - name: Begin CI... - uses: actions/checkout@v2 - - uses: actions/cache@v2 + uses: actions/checkout@v3 + - uses: actions/cache@v3 with: path: '**/node_modules' key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/yarn.lock') }} @@ -71,8 +71,8 @@ jobs: steps: - name: Begin CI... - uses: actions/checkout@v2 - - uses: actions/cache@v2 + uses: actions/checkout@v3 + - uses: actions/cache@v3 with: path: '**/node_modules' key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/yarn.lock') }} diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml new file mode 100644 index 0000000..52ce28f --- /dev/null +++ b/.github/workflows/prepare-release.yml @@ -0,0 +1,55 @@ +name: Prepare Release + +on: + workflow_dispatch: + push: + tags: + - '**' + +env: + CI: true + +permissions: + contents: read + +jobs: + build: + permissions: + contents: write # for softprops/action-gh-release to create GitHub release + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [18] + + steps: + - uses: actions/checkout@v3 + + - run: git fetch --tags -f + + - name: Resolve version + id: vars + run: | + echo "TAG_NAME=${{ github.ref_name }}" >> $GITHUB_ENV + + - name: Get release notes + run: | + RELEASE_NOTES=$(npm run release-notes $TAG_NAME --silent) + echo "RELEASE_NOTES<> $GITHUB_ENV + echo "$RELEASE_NOTES" >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + registry-url: 'https://registry.npmjs.org' + + - name: Release + uses: softprops/action-gh-release@v1 + with: + draft: true + tag_name: ${{ env.TAG_NAME }} + body: | + ${{ env.RELEASE_NOTES }} diff --git a/.github/workflows/release-insiders.yml b/.github/workflows/release-insiders.yml index 4016c30..3d9b8a2 100644 --- a/.github/workflows/release-insiders.yml +++ b/.github/workflows/release-insiders.yml @@ -17,17 +17,17 @@ jobs: node-version: [16] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} registry-url: 'https://registry.npmjs.org' - name: Use cached node_modules id: cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: '**/node_modules' key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/yarn.lock') }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..c0496b0 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,63 @@ +name: Release + +on: + release: + types: [published] + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read + +env: + CI: true + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [16] + + steps: + - uses: actions/checkout@v3 + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + registry-url: 'https://registry.npmjs.org' + + - name: Use cached node_modules + id: cache + uses: actions/cache@v3 + with: + path: '**/node_modules' + key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + nodeModules- + + - name: Install dependencies + run: yarn install --frozen-lockfile + env: + CI: true + + - name: Test + run: | + yarn test || yarn test || yarn test || exit 1 + env: + CI: true + + - name: Calculate environment variables + run: | + echo "TAG_NAME=${{ github.event.tag_name }}" >> $GITHUB_ENV + echo "RELEASE_CHANNEL=$(npm run release-channel $TAG_NAME --silent)" >> $GITHUB_ENV + echo "PACKAGE_PATH=$(npm run package-path $TAG_NAME --silent)" >> $GITHUB_ENV + + - name: Publish + run: npm publish ${{ env.PACKAGE_PATH }} --tag ${{ env.RELEASE_CHANNEL }} + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/package.json b/package.json index 13dfe2b..725b773 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,10 @@ "build": "npm-run-all -p 'react build' 'vue build'", "test": "./scripts/test.sh", "lint": "./scripts/lint.sh", - "lint-check": "CI=true ./scripts/lint.sh" + "lint-check": "CI=true ./scripts/lint.sh", + "release-channel": "node ./scripts/release-channel.js", + "release-notes": "node ./scripts/release-notes.js", + "package-path": "node ./scripts/package-path.js" }, "husky": { "hooks": { diff --git a/scripts/package-path.js b/scripts/package-path.js new file mode 100644 index 0000000..5688e69 --- /dev/null +++ b/scripts/package-path.js @@ -0,0 +1,15 @@ +// Given a version, figure out what the release notes are so that we can use this to pre-fill the +// relase notes on a GitHub release for the current version. + +let path = require('path') +let { execSync } = require('child_process') + +let tag = process.argv[2] || execSync(`git describe --tags --abbrev=0`).toString().trim() +let pkgPath = path.resolve( + __dirname, + '..', + 'packages', + tag.slice(0, tag.indexOf('@', 1)).replace('/', '-') +) + +console.log('./' + path.relative(process.cwd(), pkgPath)) diff --git a/scripts/release-channel.js b/scripts/release-channel.js new file mode 100644 index 0000000..01aaf57 --- /dev/null +++ b/scripts/release-channel.js @@ -0,0 +1,25 @@ +// Given a version, figure out what the release channel is so that we can publish to the correct +// channel on npm. +// +// E.g.: +// +// 1.2.3 -> latest (default) +// 0.0.0-insiders.ffaa88 -> insiders +// 4.1.0-alpha.4 -> alpha + +let tag = process.argv[2] || execSync(`git describe --tags --abbrev=0`).toString().trim() +let pkgPath = path.resolve( + __dirname, + '..', + 'packages', + tag.slice(0, tag.indexOf('@', 1)).replace('/', '-') +) + +let version = require(path.resolve(pkgPath, 'package.json')).version + +let match = /\d+\.\d+\.\d+-(.*)\.\d+/g.exec(version) +if (match) { + console.log(match[1]) +} else { + console.log('latest') +} diff --git a/scripts/release-notes.js b/scripts/release-notes.js new file mode 100644 index 0000000..022bf61 --- /dev/null +++ b/scripts/release-notes.js @@ -0,0 +1,29 @@ +// Given a version, figure out what the release notes are so that we can use this to pre-fill the +// relase notes on a GitHub release for the current version. + +let path = require('path') +let fs = require('fs') +let { execSync } = require('child_process') + +let tag = process.argv[2] || execSync(`git describe --tags --abbrev=0`).toString().trim() +let pkgPath = path.resolve( + __dirname, + '..', + 'packages', + tag.slice(0, tag.indexOf('@', 1)).replace('/', '-') +) + +let version = require(path.resolve(pkgPath, 'package.json')).version + +let changelog = fs.readFileSync(path.resolve(pkgPath, 'CHANGELOG.md'), 'utf8') +let match = new RegExp( + `## \\[${version}\\] - (.*)\\n\\n([\\s\\S]*?)\\n(?:(?:##\\s)|(?:\\[))`, + 'g' +).exec(changelog) + +if (match) { + let [, , notes] = match + console.log(notes.trim()) +} else { + console.log(`Placeholder release notes for version: v${version}`) +}