diff --git a/.github/workflows/changesets.yml b/.github/workflows/changesets.yml new file mode 100644 index 000000000..0d83ca71d --- /dev/null +++ b/.github/workflows/changesets.yml @@ -0,0 +1,59 @@ +name: Changesets + +on: + push: + branches: + - master + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + +jobs: + changesets: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + # Set Git operations with the bot PAT since we have tag protection rule + token: ${{ secrets.BOT_PAT }} + fetch-depth: 0 + + - name: Setup Node and pnpm + uses: silverhand-io/actions-node-pnpm-run-steps@v2 + with: + node: 18 + + - name: Import GPG key + uses: crazy-max/ghaction-import-gpg@v5 + with: + gpg_private_key: ${{ secrets.BOT_GPG_KEY }} + passphrase: ${{ secrets.BOT_GPG_PASSPHRASE }} + git_user_signingkey: true + git_commit_gpgsign: true + git_tag_gpgsign: true + + - name: Configure Git user + run: | + git config --global user.email bot@silverhand.io + git config --global user.name silverhand-bot + + - name: Version packages + run: | + pnpm changeset version + pnpm i --no-frozen-lockfile + git status + + - name: Create pull request + if: github.event_name == 'push' + uses: peter-evans/create-pull-request@v4 + with: + token: ${{ secrets.BOT_PAT }} + commit-message: 'release: version packages' + committer: silverhand-bot + author: silverhand-bot + base: master + branch: release/version-packages + title: 'release: version packages' + body: 'This is an automatic pull request from the result of `pnpm changeset version` command. Merge it will trigger the publish flow for versioned packages.' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d044ebf20..7f7d0005e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -78,19 +78,15 @@ jobs: app-name: logto-dev images: svhd/logto:edge - release-changesets: + # Publish packages and create git tags if needed + publish-and-tag: runs-on: ubuntu-latest env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTOMATION_TOKEN }} + NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTOMATION_TOKEN }} if: ${{ !startsWith(github.ref, 'refs/tags/') }} - steps: - - uses: actions/checkout@v3 - with: - # Set Git operations with the bot PAT since we have tag protection rule - token: ${{ secrets.BOT_PAT }} - fetch-depth: 0 + steps: - name: Setup Node and pnpm uses: silverhand-io/actions-node-pnpm-run-steps@v2 @@ -103,25 +99,8 @@ jobs: git_commit_gpgsign: true git_tag_gpgsign: true - - name: Configure Git user - run: | - git config --global user.email bot@silverhand.io - git config --global user.name silverhand-bot - - - name: Create release pull request - uses: changesets/action@v1 - with: - # Use our customized publish flow. See https://github.com/changesets/changesets/issues/833 for the limit of changesets. - publish: node .scripts/publish.js - # `changeset version` won't run version lifecycle scripts, see https://github.com/changesets/changesets/issues/860 - version: pnpm ci:version - commit: 'release: version packages' - title: 'release: version packages' - # Create by our rules defined in `/.changeset/README.md`. - createGithubReleases: false - setupGitUser: false - env: - GITHUB_TOKEN: ${{ secrets.BOT_PAT }} + - name: Publish + run: node .script/publish.js create-github-release: environment: release diff --git a/.scripts/merge-eslint-reports.js b/.scripts/merge-eslint-reports.js index 9c57ce91c..e6da18e53 100644 --- a/.scripts/merge-eslint-reports.js +++ b/.scripts/merge-eslint-reports.js @@ -1,5 +1,4 @@ -const fs = require('fs'); -const path = require('path'); +import fs from 'fs'; const directories = [ ...fs.readdirSync('./packages'), diff --git a/.scripts/packages-meta.js b/.scripts/packages-meta.js new file mode 100644 index 000000000..044aac30b --- /dev/null +++ b/.scripts/packages-meta.js @@ -0,0 +1,17 @@ +import { execSync } from 'node:child_process'; +import changesetConfig from '../.changeset/config.json' assert { type: 'json' }; + +export { default as changesetConfig } from '../.changeset/config.json' assert { type: 'json' }; + +export const corePackageName = '@logto/core'; +/** @type {Array<{ name: string; version?: string; path: string; private: boolean; }>} */ +export const allPackages = JSON + .parse(execSync('pnpm recursive list --depth=-1 --json', { encoding: 'utf8' })) + .filter(({ name }) => !name.endsWith('/root')); + +export const mainPackages = [...changesetConfig.fixed].map(([first]) => first); + +export const configuredPackages = new Set(changesetConfig.fixed.flat()); +export const singlePackages = allPackages + .filter(({ name }) => !configuredPackages.has(name)) + .map(({ name }) => name); diff --git a/.scripts/publish.js b/.scripts/publish.js index 258a91efd..4213897b8 100644 --- a/.scripts/publish.js +++ b/.scripts/publish.js @@ -1,22 +1,17 @@ /** * This script runs the following tasks: * - * 1. Tag main packages defined in `.changeset/config.json` if they are not tagged with the current version in `package.json`; + * 1. Tag the first package of fixed version groups defined in `.changeset/config.json` and other single packages if they are not tagged with the current version in `package.json`; * 2. If no new git tag added, exit; * 3. If at least one new git tag found, run `pnpm -r publish` and `git push --tags`. * * The subsequential release tasks, such as create GitHub release and build Docker image, will be took over by GitHub workflows. */ -const { execSync } = require('child_process'); -const changesetConfig = require('../.changeset/config.json'); +import { execSync } from 'child_process'; +import { mainPackages, allPackages, singlePackages, corePackageName } from './packages-meta.js'; -const corePackageName = '@logto/core'; -/** @type {Array<{ name: string; version?: string; path: string; private: boolean; }>} */ -const allPackages = JSON.parse(execSync('pnpm recursive list --depth=-1 --json', { encoding: 'utf8' })); -const mainPackages = [...changesetConfig.fixed, ...changesetConfig.linked].map(([first]) => first); - -const taggedPackages = mainPackages +const taggedPackages = [...mainPackages, ...singlePackages] .map((packageName) => { const packageInfo = allPackages.find(({ name }) => name === packageName); diff --git a/commitlint.config.js b/commitlint.config.cjs similarity index 100% rename from commitlint.config.js rename to commitlint.config.cjs diff --git a/lint-staged.config.js b/lint-staged.config.js index 54645ebda..56a1238f6 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -1,4 +1,4 @@ -module.exports = { +export default { '*.ts?(x)': ['eslint --cache --fix', () => 'tsc -p tsconfig.json --noEmit'], '*.scss': 'stylelint --fix', }; diff --git a/package.json b/package.json index 73774909e..b46ddfcc3 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "@logto/root", "private": true, "license": "MPL-2.0", + "type": "module", "scripts": { "preinstall": "npx only-allow pnpm", "prepare": "if test \"$NODE_ENV\" != \"production\" && test \"$CI\" != \"true\" ; then husky install ; fi",