diff --git a/.github/auto-issue-templates/new-node-lts.md b/.github/auto-issue-templates/new-node-lts.md new file mode 100644 index 0000000..a151330 --- /dev/null +++ b/.github/auto-issue-templates/new-node-lts.md @@ -0,0 +1,16 @@ +# New Node.js LTS version detected + +_Issue created automatically by a Github action._ + +A new Node.js LTS version has been detected: `{{ steps.check-version.outputs.new_lts_version }}`. + +Please test the Log4brains project against this version and update the supported versions accordingly. + +- [ ] Update the LTS version in `.nvmrc` +- [ ] Run `nvm use` and ensure `node -v` returns the new LTS version +- [ ] Run `rm -rf node_modules && yarn install` +- [ ] Run all the quality checks described in CONTRIBUTNG.md +- [ ] Run and test the app manually +- [ ] Fix the potential bugs +- [ ] Update `.github/supported_nodejs_versions.json`: add the new LTS version and remove the ones that are no longer supported (see [Node.js release schedule](https://github.com/nodejs/release#release-schedule)) +- [ ] Update all `engine.node` fields in `package.json` files diff --git a/.github/supported_nodejs_versions.json b/.github/supported_nodejs_versions.json new file mode 100644 index 0000000..6581d5f --- /dev/null +++ b/.github/supported_nodejs_versions.json @@ -0,0 +1,3 @@ +{ + "versions": ["18.x", "20.x"] +} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index bd84324..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,259 +0,0 @@ -# Inspired from https://github.com/backstage/backstage/blob/master/.github/workflows/ci.yml. Thanks! -# See ci.yml for info on `quality` and `tests` stages -name: Build -on: - workflow_dispatch: - push: - branches: - - develop - paths: - - "packages/**" - - "!packages/**/CHANGELOG.md" # filters out changes made by lerna - - "!packages/**/package.json" # filters out changes made by lerna - - ".github/workflows/build.yml" - -defaults: - run: - shell: bash - -jobs: - quality: - strategy: - # We use a matrix even if it's not needed here to be able to re-use the same Yarn setup snippet everywhere - matrix: - os: [ubuntu-latest] - node-version: [20.x] # Active LTS (https://github.com/nodejs/release) - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v2 - - # Beginning of yarn setup [KEEP IN SYNC BETWEEN ALL WORKFLOWS] (copy/paste of ci.yml's snippet) - - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - registry-url: https://registry.npmjs.org/ - - name: cache all node_modules - id: cache-modules - uses: actions/cache@v2 - with: - path: "**/node_modules" - key: ${{ runner.os }}-v${{ matrix.node-version }}-node_modules-${{ hashFiles('yarn.lock', '**/package.json') }} - - name: find location of global yarn cache - id: yarn-cache - if: steps.cache-modules.outputs.cache-hit != 'true' - run: echo "::set-output name=dir::$(yarn cache dir)" - - name: cache global yarn cache - uses: actions/cache@v2 - if: steps.cache-modules.outputs.cache-hit != 'true' - with: - path: ${{ steps.yarn-cache.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - name: yarn install - if: steps.cache-modules.outputs.cache-hit != 'true' - run: yarn install --frozen-lockfile - # End of yarn setup - - # TODO: make dev & test work without having to build everything (inspiration: https://github.com/Izhaki/mono.ts) - - name: build - run: yarn build - - - name: format - run: yarn format - - - name: lint - run: yarn lint - - tests: - needs: quality - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - node-version: - - 20.x # Active LTS (https://github.com/nodejs/release) - - 18.x # Maintenance LTS - exclude: # these cases are tested after the release with E2E tests - - os: windows-latest - node-version: 18.x - - os: windows-latest - node-version: 18.x - - os: macos-latest - node-version: 18.x - - os: macos-latest - node-version: 18.x - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 # fetch all history to make Jest snapshot tests work - - # Beginning of yarn setup [KEEP IN SYNC BETWEEN ALL WORKFLOWS] (copy/paste of ci.yml's snippet) - - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - registry-url: https://registry.npmjs.org/ - - name: cache all node_modules - id: cache-modules - uses: actions/cache@v2 - with: - path: "**/node_modules" - key: ${{ runner.os }}-v${{ matrix.node-version }}-node_modules-${{ hashFiles('yarn.lock', '**/package.json') }} - - name: find location of global yarn cache - id: yarn-cache - if: steps.cache-modules.outputs.cache-hit != 'true' - run: echo "::set-output name=dir::$(yarn cache dir)" - - name: cache global yarn cache - uses: actions/cache@v2 - if: steps.cache-modules.outputs.cache-hit != 'true' - with: - path: ${{ steps.yarn-cache.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - name: yarn install - if: steps.cache-modules.outputs.cache-hit != 'true' - run: yarn install --frozen-lockfile - # End of yarn setup - - # We have to build all the packages before the tests - # Because init-log4brains's integration tests use @log4brains/cli, which uses @log4brains/core - # TODO: we should separate tests that require built packages of the others, to get a quicker feedback - # Once it's done, we should add "yarn test" in each package's preVersion script - - name: build - run: | - yarn build - yarn link-cli - echo "$(yarn global bin)" >> $GITHUB_PATH - - - name: typescript checks - run: yarn typescript - - - name: test - run: yarn test - - - name: E2E tests - run: yarn e2e - - publish-pages: - needs: tests - strategy: - # We use a matrix even if it's not needed here to be able to re-use the same Yarn setup snippet everywhere - matrix: - os: [ubuntu-latest] - node-version: [20.x] # Active LTS (https://github.com/nodejs/release) - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v2 - with: - persist-credentials: false # required by JamesIves/github-pages-deploy-action - fetch-depth: 0 # required by Log4brains to work correctly (needs the whole Git history) - - # Beginning of yarn setup [KEEP IN SYNC BETWEEN ALL WORKFLOWS] (copy/paste of ci.yml's snippet) - - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - registry-url: https://registry.npmjs.org/ - - name: cache all node_modules - id: cache-modules - uses: actions/cache@v2 - with: - path: "**/node_modules" - key: ${{ runner.os }}-v${{ matrix.node-version }}-node_modules-${{ hashFiles('yarn.lock', '**/package.json') }} - - name: find location of global yarn cache - id: yarn-cache - if: steps.cache-modules.outputs.cache-hit != 'true' - run: echo "::set-output name=dir::$(yarn cache dir)" - - name: cache global yarn cache - uses: actions/cache@v2 - if: steps.cache-modules.outputs.cache-hit != 'true' - with: - path: ${{ steps.yarn-cache.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - name: yarn install - if: steps.cache-modules.outputs.cache-hit != 'true' - run: yarn install --frozen-lockfile - # End of yarn setup - - - name: build - run: | - yarn build - yarn link-cli - echo "$(yarn global bin)" >> $GITHUB_PATH - - - name: build self knowledge base - env: - HIDE_LOG4BRAINS_VERSION: "1" # TODO: use lerna to bump the version temporarily here so we don't have to hide it - run: log4brains build --basePath /${GITHUB_REPOSITORY#*/}/adr - - - name: publish self knowledge base - uses: JamesIves/github-pages-deploy-action@3.7.1 - with: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - BRANCH: gh-pages - FOLDER: .log4brains/out - TARGET_FOLDER: adr - - release: - needs: publish-pages # we could perform this step in parallel but this acts as a last end-to-end test before releasing - strategy: - # We use a matrix even if it's not needed here to be able to re-use the same Yarn setup snippet everywhere - matrix: - os: [ubuntu-latest] - node-version: [20.x] # Active LTS (https://github.com/nodejs/release) - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # fetch all history for Lerna (https://stackoverflow.com/a/60184319/9285308) - ssh-key: ${{ secrets.LERNA_GITHUB_DEPLOY_KEY }} # so that Lerna is able to push to the protected branch (https://github.com/orgs/community/discussions/25305#discussioncomment-10728028) - - - name: fetch all git tags for Lerna # (https://stackoverflow.com/a/60184319/9285308) - run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* || true - - # Beginning of yarn setup [KEEP IN SYNC BETWEEN ALL WORKFLOWS] (copy/paste of ci.yml's snippet) - - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - registry-url: https://registry.npmjs.org/ - - name: cache all node_modules - id: cache-modules - uses: actions/cache@v2 - with: - path: "**/node_modules" - key: ${{ runner.os }}-v${{ matrix.node-version }}-node_modules-${{ hashFiles('yarn.lock', '**/package.json') }} - - name: find location of global yarn cache - id: yarn-cache - if: steps.cache-modules.outputs.cache-hit != 'true' - run: echo "::set-output name=dir::$(yarn cache dir)" - - name: cache global yarn cache - uses: actions/cache@v2 - if: steps.cache-modules.outputs.cache-hit != 'true' - with: - path: ${{ steps.yarn-cache.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - name: yarn install - if: steps.cache-modules.outputs.cache-hit != 'true' - run: yarn install --frozen-lockfile - # End of yarn setup - - - name: build - run: yarn build - - - name: git identity - run: | - git config --global user.name 'github-actions[bot]' - git config --global user.email 'github-actions[bot]@users.noreply.github.com' - - name: release and publish to NPM - run: yarn lerna publish --yes --conventional-commits --conventional-prerelease --force-publish --dist-tag alpha --exact --create-release github - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index ed8db7e..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,144 +0,0 @@ -# Inspired from https://github.com/backstage/backstage/blob/master/.github/workflows/ci.yml. Thanks! -name: CI -on: - workflow_dispatch: - pull_request: - -defaults: - run: - shell: bash - -jobs: - quality: - strategy: - # We use a matrix even if it's not needed here to be able to re-use the same Yarn setup snippet everywhere - matrix: - os: [ubuntu-latest] - node-version: [20.x] # Active LTS (https://github.com/nodejs/release) - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v2 - - # Beginning of yarn setup [KEEP IN SYNC BETWEEN ALL WORKFLOWS] - # TODO: create a dedicated composite GitHub Action to avoid copy/pastes everywhere - - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - registry-url: https://registry.npmjs.org/ # needed for auth when publishing - - # Cache every node_modules folder inside the monorepo - - name: cache all node_modules - id: cache-modules - uses: actions/cache@v2 - with: - path: "**/node_modules" - # We use both yarn.lock and package.json as cache keys to ensure that - # changes to local monorepo packages bust the cache. - key: ${{ runner.os }}-v${{ matrix.node-version }}-node_modules-${{ hashFiles('yarn.lock', '**/package.json') }} - - # If we get a cache hit for node_modules, there's no need to bring in the global - # yarn cache or run yarn install, as all dependencies will be installed already. - - - name: find location of global yarn cache - id: yarn-cache - if: steps.cache-modules.outputs.cache-hit != 'true' - run: echo "::set-output name=dir::$(yarn cache dir)" - - - name: cache global yarn cache - uses: actions/cache@v2 - if: steps.cache-modules.outputs.cache-hit != 'true' - with: - path: ${{ steps.yarn-cache.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - name: yarn install - if: steps.cache-modules.outputs.cache-hit != 'true' - run: yarn install --frozen-lockfile - # End of yarn setup - - # TODO: make dev & test work without having to build everything (inspiration: https://github.com/Izhaki/mono.ts) - - name: build - run: yarn build - - - name: format - run: yarn format - - - name: lint - run: yarn lint - - tests: - needs: quality - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - node-version: [20.x] # Active LTS (https://github.com/nodejs/release); we test other versions in the main Build workflow because it's too slow - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 # fetch all history to make Jest snapshot tests work - - - name: fetch branch develop - run: git fetch origin develop - - # Beginning of yarn setup [KEEP IN SYNC BETWEEN ALL WORKFLOWS] (copy/paste of the snippet above) - - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - registry-url: https://registry.npmjs.org/ - - name: cache all node_modules - id: cache-modules - uses: actions/cache@v2 - with: - path: "**/node_modules" - key: ${{ runner.os }}-v${{ matrix.node-version }}-node_modules-${{ hashFiles('yarn.lock', '**/package.json') }} - - name: find location of global yarn cache - id: yarn-cache - if: steps.cache-modules.outputs.cache-hit != 'true' - run: echo "::set-output name=dir::$(yarn cache dir)" - - name: cache global yarn cache - uses: actions/cache@v2 - if: steps.cache-modules.outputs.cache-hit != 'true' - with: - path: ${{ steps.yarn-cache.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - name: yarn install - if: steps.cache-modules.outputs.cache-hit != 'true' - run: yarn install --frozen-lockfile - # End of yarn setup - - - name: check for yarn.lock changes - id: yarn-lock - run: git diff --quiet origin/develop HEAD -- yarn.lock - continue-on-error: true - # - steps.yarn-lock.outcome == 'success' --> yarn.lock was not changed - # - steps.yarn-lock.outcome == 'failure' --> yarn.lock was changed - - # We have to build all the packages before the tests - # Because init-log4brains's integration tests use @log4brains/cli, which uses @log4brains/core - # TODO: we should separate tests that require built packages of the others, to get a quicker feedback - # Once it's done, we should add "yarn test" in each package's preVersion script - - name: build - run: | - yarn build - yarn link-cli - echo "$(yarn global bin)" >> $GITHUB_PATH - - - name: typescript checks - run: yarn typescript - - - name: test changed packages - if: ${{ steps.yarn-lock.outcome == 'success' }} - run: yarn test --since origin/develop - - - name: test all packages - if: ${{ steps.yarn-lock.outcome == 'failure' }} - run: yarn test - - - name: E2E tests - run: yarn e2e diff --git a/.github/workflows/on-merge-to-develop.yml b/.github/workflows/on-merge-to-develop.yml new file mode 100644 index 0000000..048099c --- /dev/null +++ b/.github/workflows/on-merge-to-develop.yml @@ -0,0 +1,113 @@ +# Inspired from https://github.com/backstage/backstage/blob/master/.github/workflows/ci.yml. Thanks! +name: On merge to develop (alpha releases) +on: + workflow_dispatch: + push: + branches: + - develop + paths: + - "packages/**" + - "!packages/**/CHANGELOG.md" # filters out changes made by lerna + - "!packages/**/package.json" # filters out changes made by lerna + - ".github/workflows/build.yml" + +defaults: + run: + shell: bash + +jobs: + quality-checks: + uses: ./.github/workflows/reusable-quality-checks.yml + + load-nodejs-supported-versions: + uses: ./.github/workflows/reusable-load-nodejs-supported-versions.yml + + # We test the current LTS on all OSes and other supported versions are only tested on Ubuntu for performance reasons + # All the other os/version tuples will be tested in the post-release E2E workflow + tests-per-nodejs-version: + needs: load-nodejs-supported-versions + strategy: + matrix: + node-version: ${{ fromJson(needs.load-supported-versions.outputs.node_versions) }} + uses: ./.github/workflows/reusable-tests.yml + with: + os: ubuntu-latest + node-version: ${{ matrix.node-version }} + + tests-LTS-per-other-os: + strategy: + matrix: + os: [windows-latest, macos-latest] + uses: ./.github/workflows/reusable-tests.yml + with: + os: ${{ matrix.os }} + node-version-file: .nvmrc # current LTS + + tests-nodejs-current: + uses: ./.github/workflows/reusable-tests.yml + with: + os: ubuntu-latest + node-version: current + experimental: true # best effort mode + + publish-pages: + needs: + - quality-checks + - tests-per-nodejs-version + - tests-LTS-per-other-os + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false # required by JamesIves/github-pages-deploy-action + fetch-depth: 0 # required by Log4brains to work correctly (needs the whole Git history) + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc # current LTS + cache: yarn + cache-dependency-path: yarn.lock + - run: yarn install --frozen-lockfile + - name: Build and link + run: | + yarn build + yarn link-cli + echo "$(yarn global bin)" >> $GITHUB_PATH + - name: Log4brains build + env: + HIDE_LOG4BRAINS_VERSION: "1" # TODO: use lerna to bump the version temporarily here so we don't have to hide it + run: log4brains build --basePath /${GITHUB_REPOSITORY#*/}/adr + - name: Publish to Github pages + uses: JamesIves/github-pages-deploy-action@3.7.1 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BRANCH: gh-pages + FOLDER: .log4brains/out + TARGET_FOLDER: adr + + release-alpha: + needs: publish-pages # we could perform this step in parallel but this acts as a last end-to-end test before releasing + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # fetch all history for Lerna (https://stackoverflow.com/a/60184319/9285308) + ssh-key: ${{ secrets.LERNA_GITHUB_DEPLOY_KEY }} # so that Lerna is able to push to the protected branch (https://github.com/orgs/community/discussions/25305#discussioncomment-10728028) + - name: Fetch all git tags for Lerna # (https://stackoverflow.com/a/60184319/9285308) + run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* || true + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc # current LTS + cache: yarn + cache-dependency-path: yarn.lock + registry-url: https://registry.npmjs.org/ # needed by lerna to push to NPM + - run: yarn install --frozen-lockfile + - run: yarn build + - name: Git identity for github-actions[bot] + run: | + git config --global user.name 'github-actions[bot]' + git config --global user.email 'github-actions[bot]@users.noreply.github.com' + - name: Run lerna publish + run: yarn lerna publish --yes --conventional-commits --conventional-prerelease --force-publish --dist-tag alpha --exact --create-release github + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/on-release-tag-alpha.yml b/.github/workflows/on-release-tag-alpha.yml new file mode 100644 index 0000000..291d83e --- /dev/null +++ b/.github/workflows/on-release-tag-alpha.yml @@ -0,0 +1,35 @@ +name: On release tag push (alpha only) +on: + workflow_dispatch: + + # Run after every alpha release to NPM + push: + tags: + - v*-alpha.* + +defaults: + run: + shell: bash + +jobs: + get-log4brains-version: + uses: ./.github/workflows/reusable-get-log4brains-version.yml + + wait-for-npm-version-to-be-published: + needs: get-log4brains-version + uses: ./.github/workflows/reusable-wait-for-npm-version-to-be-published.yml + with: + npm-package: log4brains + npm-version: ${{ needs.get-log4brains-version.outputs.version }} + + build-and-push: + needs: wait-for-npm-version-to-be-published + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build and push the latest alpha Docker image + run: MDF_BRANCH_TAG=alpha make -C docker release version-tag branch-tag diff --git a/.github/workflows/on-release-tag.yml b/.github/workflows/on-release-tag.yml new file mode 100644 index 0000000..70f9814 --- /dev/null +++ b/.github/workflows/on-release-tag.yml @@ -0,0 +1,55 @@ +name: On release tag push +on: + workflow_dispatch: + + # Run after every release to NPM (alpha and stable) + push: + tags: + - v* + +defaults: + run: + shell: bash + +jobs: + get-log4brains-version: + uses: ./.github/workflows/reusable-get-log4brains-version.yml + + wait-for-npm-version-to-be-published: + needs: get-log4brains-version + uses: ./.github/workflows/reusable-wait-for-npm-version-to-be-published.yml + with: + npm-package: log4brains + npm-version: ${{ needs.get-log4brains-version.outputs.version }} + + load-nodejs-supported-versions: + uses: ./.github/workflows/reusable-load-nodejs-supported-versions.yml + + e2e-tests: + needs: + - load-nodejs-supported-versions + - get-log4brains-version + - wait-for-npm-version-to-be-published + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + node-version: ${{ fromJson(needs.load-supported-versions.outputs.node_versions) }} + uses: ./.github/workflows/reusable-e2e-tests.yml + with: + npm-package-fullname: log4brains@${{ needs.get-log4brains-version.outputs.version }} + os: ${{ matrix.os }} + node-version: ${{ matrix.node-version }} + + e2e-tests-nodejs-current: + needs: + - get-log4brains-version + - wait-for-npm-version-to-be-published + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + uses: ./.github/workflows/reusable-e2e-tests.yml + with: + npm-package-fullname: log4brains@${{ needs.get-log4brains-version.outputs.version }} + os: ${{ matrix.os }} + node-version: current + experimental: true # best effort mode diff --git a/.github/workflows/post-release-docker-hub-alpha.yml b/.github/workflows/post-release-docker-hub-alpha.yml deleted file mode 100644 index d855b23..0000000 --- a/.github/workflows/post-release-docker-hub-alpha.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Post-release Docker Hub alpha -on: - workflow_dispatch: - - # Run after every alpha release to NPM - push: - tags: - - v*-alpha.* - -jobs: - build-and-release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: login to Docker Hub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: build and release the latest alpha Docker image - run: MDF_BRANCH_TAG=alpha make -C docker release version-tag branch-tag diff --git a/.github/workflows/post-release-e2e-alpha.yml b/.github/workflows/post-release-e2e-alpha.yml deleted file mode 100644 index 36b3569..0000000 --- a/.github/workflows/post-release-e2e-alpha.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Post-release E2E alpha -on: - workflow_dispatch: - - # Run after every alpha release to NPM - push: - tags: - - v*-alpha.* - -jobs: - e2e: - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - node-version: - - 20.x # Active LTS (https://github.com/nodejs/release) - - 18.x # Maintenance LTS - runs-on: ${{ matrix.os }} - steps: - - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - registry-url: https://registry.npmjs.org/ - - - name: install - run: npm install -g log4brains@alpha - - - name: test # TODO: test the preview add some assertions :-) For now we just check the exit codes. Or manage to run e2e-tests/e2e-launcher.js from here - run: | - log4brains --version - log4brains init --defaults - log4brains adr list - log4brains build diff --git a/.github/workflows/post-release-e2e.yml b/.github/workflows/post-release-e2e.yml deleted file mode 100644 index 69fed23..0000000 --- a/.github/workflows/post-release-e2e.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Post-release E2E -on: - workflow_dispatch: - - # Run after every release to NPM - push: - tags: - - v* - - "!v*-alpha.*" - - # Run on every Wednesday to check possible regressions caused by dependency updates - # Like this one: https://github.com/thomvaill/log4brains/issues/27 - schedule: - - cron: "0 4 * * 3" - -jobs: - e2e: - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - node-version: - - 20.x # Active LTS (https://github.com/nodejs/release) - - 18.x # Maintenance LTS - runs-on: ${{ matrix.os }} - steps: - - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - registry-url: https://registry.npmjs.org/ - - - name: install - run: npm install -g log4brains - - - name: test # TODO: test the preview add some assertions :-) For now we just check the exit codes. Or manage to run e2e-tests/e2e-launcher.js from here - run: | - log4brains --version - log4brains init --defaults - log4brains adr list - log4brains build diff --git a/.github/workflows/pull-request-checks.yml b/.github/workflows/pull-request-checks.yml new file mode 100644 index 0000000..7db3245 --- /dev/null +++ b/.github/workflows/pull-request-checks.yml @@ -0,0 +1,33 @@ +# Inspired from https://github.com/backstage/backstage/blob/master/.github/workflows/ci.yml. Thanks! +name: Pull request checks +on: + workflow_dispatch: + pull_request: + +defaults: + run: + shell: bash + +jobs: + quality-checks: + uses: ./.github/workflows/reusable-quality-checks.yml + + # We only test the LTS on all OSes for performance reasons + # Other versions will be tested on the main workflow after the merge + tests-LTS-per-os: + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + uses: ./.github/workflows/reusable-tests.yml + with: + only-changed-packages: true # for performance + os: ${{ matrix.os }} + node-version-file: .nvmrc # current LTS + + tests-nodejs-current: + uses: ./.github/workflows/reusable-tests.yml + with: + only-changed-packages: true # for performance + os: ubuntu-latest + node-version: current + experimental: true # best effort mode diff --git a/.github/workflows/reusable-e2e-tests.yml b/.github/workflows/reusable-e2e-tests.yml new file mode 100644 index 0000000..675e52d --- /dev/null +++ b/.github/workflows/reusable-e2e-tests.yml @@ -0,0 +1,47 @@ +on: + workflow_call: + inputs: + npm-package-fullname: + required: true + type: string + experimental: + required: false + type: boolean + default: false + os: + required: true + type: string + # Set only one of these two inputs: + node-version: + required: false + type: string + node-version-file: + required: false + type: string + +defaults: + run: + shell: bash + +jobs: + e2e-tests: + runs-on: ${{ inputs.os }} + continue-on-error: ${{ inputs.experimental }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # required by Log4brains to work correctly (needs the whole Git history) + - uses: actions/setup-node@v4 + with: + node-version-file: ${{ inputs.node-version-file }} + node-version: ${{ inputs.node-version }} + + - run: npm install -g ${{ inputs.npm-package-fullname }} + + # TODO: test the preview and add some assertions :-) For now we just check the exit codes. Or manage to run e2e-tests/e2e-launcher.js from here + - name: Tests + run: | + log4brains --version + log4brains init --defaults + log4brains adr list + log4brains build diff --git a/.github/workflows/reusable-get-log4brains-version.yml b/.github/workflows/reusable-get-log4brains-version.yml new file mode 100644 index 0000000..c5ad221 --- /dev/null +++ b/.github/workflows/reusable-get-log4brains-version.yml @@ -0,0 +1,22 @@ +on: + workflow_call: + outputs: + version: + description: "Log4brains current version" + value: ${{ jobs.get-log4brains-version.outputs.version }} + +defaults: + run: + shell: bash + +jobs: + get-log4brains-version: + runs-on: ubuntu-latest + outputs: + version: ${{ steps.get-version.outputs.version }} + steps: + - name: Get log4brains version from lerna.json + id: get-version + run: | + version="$(cat lerna.json | jq -r .version)" + echo "::set-output name=version::$version" diff --git a/.github/workflows/reusable-load-nodejs-supported-versions.yml b/.github/workflows/reusable-load-nodejs-supported-versions.yml new file mode 100644 index 0000000..4c91d76 --- /dev/null +++ b/.github/workflows/reusable-load-nodejs-supported-versions.yml @@ -0,0 +1,22 @@ +on: + workflow_call: + outputs: + node_versions: + description: "Node.js versions officially supported by the project" + value: ${{ jobs.load-nodejs-supported-versions.outputs.node_versions }} + +defaults: + run: + shell: bash + +jobs: + load-nodejs-supported-versions: + runs-on: ubuntu-latest + outputs: + node_versions: ${{ steps.get-versions.outputs.node_versions }} + steps: + - name: Get supported Node.js versions from JSON file + id: get-versions + run: | + node_versions=$(cat .github/supported_nodejs_versions.json | jq -r '.versions | @json') + echo "::set-output name=node_versions::$node_versions" diff --git a/.github/workflows/reusable-quality-checks.yml b/.github/workflows/reusable-quality-checks.yml new file mode 100644 index 0000000..3d61982 --- /dev/null +++ b/.github/workflows/reusable-quality-checks.yml @@ -0,0 +1,24 @@ +on: + workflow_call: + +defaults: + run: + shell: bash + +jobs: + quality-checks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc # current LTS + cache: yarn + cache-dependency-path: yarn.lock + - run: yarn install --frozen-lockfile + + # TODO: make dev & test work without having to build everything (inspiration: https://github.com/Izhaki/mono.ts) + # - run: yarn typescript + - run: yarn build + - run: yarn format + - run: yarn lint diff --git a/.github/workflows/reusable-tests.yml b/.github/workflows/reusable-tests.yml new file mode 100644 index 0000000..bc45901 --- /dev/null +++ b/.github/workflows/reusable-tests.yml @@ -0,0 +1,68 @@ +on: + workflow_call: + inputs: + only-changed-packages: + required: false + type: boolean + default: false # by default it will test all packages; also if only-changed-packages=true and yarn.lock has changed: it will test all packages too + experimental: + required: false + type: boolean + default: false + os: + required: true + type: string + # Set only one of these two inputs: + node-version: + required: false + type: string + node-version-file: + required: false + type: string + +defaults: + run: + shell: bash + +jobs: + tests: + runs-on: ${{ inputs.os }} + continue-on-error: ${{ inputs.experimental }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # fetch all history to make Jest snapshot tests work + - uses: actions/setup-node@v4 + with: + node-version-file: ${{ inputs.node-version-file }} + node-version: ${{ inputs.node-version }} + cache: yarn + cache-dependency-path: yarn.lock + - run: yarn install --frozen-lockfile + + - name: Check for yarn.lock changes + id: yarn-lock + run: git diff --quiet origin/develop HEAD -- yarn.lock + continue-on-error: true + # - steps.yarn-lock.outcome == 'success' --> yarn.lock was not changed + # - steps.yarn-lock.outcome == 'failure' --> yarn.lock was changed + + # We have to build all the packages before the tests + # Because init-log4brains's integration tests use @log4brains/cli, which uses @log4brains/core + # TODO: we should separate tests that require built packages of the others, to get a quicker feedback + # Once it's done, we should add "yarn test" in each package's preVersion script + - run: yarn build + + - name: Test only packages that have changed compared to the main branch + if: ${{ inputs.only-changed-packages && steps.yarn-lock.outcome == 'success' }} + run: yarn test --since origin/develop + + - name: Test all packages (only-changed-packages=false or yarn.lock has changed) + if: ${{ !inputs.only-changed-packages || steps.yarn-lock.outcome == 'failure' }} + run: yarn test + + - name: E2E tests + run: | + yarn link-cli + echo "$(yarn global bin)" >> $GITHUB_PATH + yarn e2e diff --git a/.github/workflows/reusable-wait-for-npm-version-to-be-published.yml b/.github/workflows/reusable-wait-for-npm-version-to-be-published.yml new file mode 100644 index 0000000..9ee7660 --- /dev/null +++ b/.github/workflows/reusable-wait-for-npm-version-to-be-published.yml @@ -0,0 +1,25 @@ +on: + workflow_call: + inputs: + npm-package: + required: true + type: string + npm-version: # only exact versions allowed, not tags like "latest" or "alpha" + required: true + type: string + wait-minutes: + required: false + type: string + default: "10" + +defaults: + run: + shell: bash + +jobs: + wait-for-npm-version-to-be-published: + runs-on: ubuntu-latest + steps: + - uses: actions/setup-node@v4 + - name: Wait + run: ./scripts/wait-for-npm-version-to-be-published.sh "${{ inputs.npm-package }}" "${{ inputs.npm-version }}" "${{ inputs.wait-minutes }}" diff --git a/.github/workflows/scheduled-weekly-e2e-stable.yml b/.github/workflows/scheduled-weekly-e2e-stable.yml new file mode 100644 index 0000000..3f23898 --- /dev/null +++ b/.github/workflows/scheduled-weekly-e2e-stable.yml @@ -0,0 +1,39 @@ +name: Weekly E2E tests (stable only) +on: + workflow_dispatch: + + # Run on every Wednesday to check possible regressions caused by dependency updates + # Like this one: https://github.com/thomvaill/log4brains/issues/27 + schedule: + - cron: "0 4 * * 3" + +defaults: + run: + shell: bash + +jobs: + load-nodejs-supported-versions: + uses: ./.github/workflows/reusable-load-nodejs-supported-versions.yml + + e2e: + needs: load-nodejs-supported-versions + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + node-version: ${{ fromJson(needs.load-supported-versions.outputs.node_versions) }} + uses: ./.github/workflows/reusable-e2e-tests.yml + with: + npm-package-fullname: log4brains # stable version + os: ${{ matrix.os }} + node-version: ${{ matrix.node-version }} + + e2e-tests-nodejs-current: + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + uses: ./.github/workflows/reusable-e2e-tests.yml + with: + npm-package-fullname: log4brains # stable version + os: ${{ matrix.os }} + node-version: current + experimental: true # best effort mode diff --git a/.github/workflows/scheduled-weekly-new-nodejs-lts-check.yml b/.github/workflows/scheduled-weekly-new-nodejs-lts-check.yml new file mode 100644 index 0000000..f4cee0f --- /dev/null +++ b/.github/workflows/scheduled-weekly-new-nodejs-lts-check.yml @@ -0,0 +1,47 @@ +name: Weekly new Node.js LTS check +on: + workflow_dispatch: + + # Run on every Sunday to check if a new Node.js LTS that we don't support is released, and create an Issue if this is the case + schedule: + - cron: "0 4 * * 0" + +defaults: + run: + shell: bash + +jobs: + load-nodejs-supported-versions: + uses: ./.github/workflows/reusable-load-nodejs-supported-versions.yml + + lts-check: + needs: load-nodejs-supported-versions + runs-on: ubuntu-latest + steps: + - name: Get latest Node.js LTS versions + run: | + curl -s https://nodejs.org/dist/index.json | jq '[.[] | select(.lts != false)] | .[0]' > latest-lts.json + CURRENT_LTS="$(jq -r '.version' latest-lts.json | sed 's/v//')" + echo "Latest LTS version: ${CURRENT_LTS}" + + - name: Compare with supported versions + id: check-version + run: | + SUPPORTED_VERSIONS="${{ needs.load-nodejs-supported-versions.outputs.node_versions }}" + if [[ ! "${SUPPORTED_VERSIONS}" =~ "${CURRENT_LTS}" ]] + then + echo "A new Node.js LTS version is available: ${CURRENT_LTS}" + echo "::set-output name=new_lts_version::${CURRENT_LTS}" + else + echo "No new Node.js LTS version detected" + fi + + - name: Create an issue if new LTS + if: steps.check-version.outputs.new_lts_version + uses: peter-evans/create-issue-from-file@v5 + with: + title: "New Node.js LTS version: ${{ steps.check-version.outputs.new_lts_version }}" + content-filepath: .github/auto-issue-templates/new-node-lts.md + labels: | + auto + maintenance diff --git a/README.md b/README.md index 00bacf0..c08ff0f 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,8 @@ License - - Build Status + + Build Status log4brains latest version @@ -168,15 +168,13 @@ jobs: build-and-publish: runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v2.3.4 + - uses: actions/checkout@v4 with: persist-credentials: false # required by JamesIves/github-pages-deploy-action fetch-depth: 0 # required by Log4brains to work correctly (needs the whole Git history) - - name: Install Node - uses: actions/setup-node@v1 + - uses: actions/setup-node@v4 with: - node-version: "14" + node-version: lts/* - name: Install and Build Log4brains run: | npm install -g log4brains @@ -298,7 +296,7 @@ Finally, you can add the ADR badge to your `README.md`! ### What are the prerequisites? -- Node.js >= 12 +- Node.js: active or maintenance LTS version (see [Node.js release schedule](https://github.com/nodejs/release#release-schedule); versions outside of this range are not guaranteed to work; "current" version is supported in a best effort mode) - NPM or Yarn - Git diff --git a/scripts/wait-for-npm-version-to-be-published.sh b/scripts/wait-for-npm-version-to-be-published.sh new file mode 100755 index 0000000..0295a0d --- /dev/null +++ b/scripts/wait-for-npm-version-to-be-published.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +set -euo pipefail + +package_name="${1:-}" +package_version="${2:-}" +wait_minutes="${3:-}" + +usage() { + echo "Usage: $0 " +} + +if [[ -z "${package_name}" ]] +then + echo "Missing package_name" + usage + exit 1 +fi + +if [[ -z "${package_version}" ]] +then + echo "Missing package_version" + usage + exit 1 +fi + +if [[ -z "${wait_minutes}" ]] || ! [[ "${wait_minutes}" =~ ^-?[0-9]+$ ]] +then + echo "Missing wait_minutes or is not a valid integer" + usage + exit 1 +fi + +echo "Checking if ${package_name}@${package_version} is available on NPM (waiting max ${wait_minutes} min)..." + +i=0 +while ! npm view "${package_name}" versions --json | jq -e --arg package_version "${package_version}" 'index($package_version)' &> /dev/null +do + if [[ ${i} -gt ${wait_minutes} ]] + then + echo "Failure for more than ${wait_minutes} minutes" + echo "Available versions:" + npm view "${package_name}" versions --json + echo "Abort" + exit 1 + fi + + echo "${package_name}@${package_version} is not available yet on NPM. Let's wait 60s..." + sleep 60 + ((i=i+1)) +done + +echo "${package_name}@${package_version} is available"