From 35c4cab38928c02a3c88a24c3cbd70c06da0d1ab Mon Sep 17 00:00:00 2001 From: akshatnema Date: Sun, 24 Nov 2024 00:06:13 +0530 Subject: [PATCH 1/5] added changeset config --- .changeset/config.json | 14 ++ .github/workflows/release-with-changesets.yml | 137 ++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 .changeset/config.json create mode 100644 .github/workflows/release-with-changesets.yml diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 00000000000..b6d4d5393be --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", + "changelog": ["@changesets/changelog-git", { "repo": "asyncapi/cli" }], + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "master", + "updateInternalDependencies": "patch", + "privatePackages": { + "version": true, + "tag": true + } +} diff --git a/.github/workflows/release-with-changesets.yml b/.github/workflows/release-with-changesets.yml new file mode 100644 index 00000000000..327dfd4eb40 --- /dev/null +++ b/.github/workflows/release-with-changesets.yml @@ -0,0 +1,137 @@ +# It does magic only if there is a package.json file in the root of the project +name: Release + +on: + push: + branches: + - master + # The below lines are not enough to have release supported for these branches + - next-spec + - next-major + - next-major-spec + - beta + - alpha + - next + +jobs: + test-nodejs: + # We just check the message of the first commit as there is always just one commit because we squash into one before merging + # "commits" contains an array of objects where one of the properties is the commit "message" + # Release workflow will be skipped if release conventional commits are not used + if: | + startsWith( github.repository, 'asyncapi/' ) && + (startsWith( github.event.commits[0].message , 'fix:' ) || + startsWith( github.event.commits[0].message, 'fix!:' ) || + startsWith( github.event.commits[0].message, 'feat:' ) || + startsWith( github.event.commits[0].message, 'chore(release):' ) || + startsWith( github.event.commits[0].message, 'feat!:' )) + name: Test NodeJS release on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + # Using macos-13 instead of latest (macos-14) due to an issue with Puppeteer and such runner. + # See: https://github.com/puppeteer/puppeteer/issues/12327 and https://github.com/asyncapi/parser-js/issues/1001 + os: [ubuntu-latest, macos-13, windows-latest] + steps: + - name: Set git to use LF # To once and for all finish the never-ending fight between Unix and Windows + run: | + git config --global core.autocrlf false + git config --global core.eol lf + shell: bash + - name: Checkout repository + uses: actions/checkout@v4 + - name: Check if Node.js project and has package.json + id: packagejson + run: test -e ./package.json && echo "exists=true" >> $GITHUB_OUTPUT || echo "exists=false" >> $GITHUB_OUTPUT + shell: bash + - if: steps.packagejson.outputs.exists == 'true' + name: Check package-lock version + uses: asyncapi/.github/.github/actions/get-node-version-from-package-lock@master + id: lockversion + - if: steps.packagejson.outputs.exists == 'true' + name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "${{ steps.lockversion.outputs.version }}" + - if: steps.lockversion.outputs.version == '18' && matrix.os == 'windows-latest' + name: Install npm cli 8 + shell: bash + # npm cli 10 is buggy because of some cache issues + run: npm install -g npm@8.19.4 + - if: steps.packagejson.outputs.exists == 'true' + name: Install dependencies + shell: bash + run: npm ci + - if: steps.packagejson.outputs.exists == 'true' + name: Run test + run: npm test --if-present + - if: failure() # Only, on failure, send a message on the 94_bot-failing-ci slack channel + name: Report workflow run status to Slack + uses: 8398a7/action-slack@v3 + with: + status: ${{ job.status }} + fields: repo,action,workflow + text: "Release workflow failed in testing job" + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CI_FAIL_NOTIFY }} + + release: + needs: [test-nodejs] + name: Publish to any of NPM, GitHub, or Docker Hub + runs-on: ubuntu-latest + steps: + - name: Set git to use LF # To once and for all finish the never-ending fight between Unix and Windows + run: | + git config --global core.autocrlf false + git config --global core.eol lf + - name: Checkout repository + uses: actions/checkout@v4 + - name: Check if Node.js project and has package.json + id: packagejson + run: test -e ./package.json && echo "exists=true" >> $GITHUB_OUTPUT || echo "exists=false" >> $GITHUB_OUTPUT + shell: bash + - if: steps.packagejson.outputs.exists == 'true' + name: Check package-lock version + uses: asyncapi/.github/.github/actions/get-node-version-from-package-lock@master + id: lockversion + - if: steps.packagejson.outputs.exists == 'true' + name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "${{ steps.lockversion.outputs.version }}" + - if: steps.packagejson.outputs.exists == 'true' + name: Install dependencies + shell: bash + run: npm ci + - if: steps.packagejson.outputs.exists == 'true' + name: Install changelog + shell: bash + # This step can be removed once the issue is fixed in the changeset package. + run: npm install @changesets/changelog-git@0.2.0 + - if: steps.packagejson.outputs.exists == 'true' + name: Publish to any of NPM, Github, and Docker Hub + #this step has 2 goals, it is either identifying that there is changeset file created and then this action creates a PR with version bump that will trigger release - or if it sees there is no changeset, and there are versions changes in package.json files, it publish new versions to NPM is they are not there yet + uses: changesets/action@v1 + id: release + with: + version: npx -p @changesets/cli@2.27.7 changeset version + commit: "chore(release): release and bump versions of packages" + title: "chore(release): release and bump versions of packages" + publish: npx -p @changesets/cli@2.27.7 changeset publish + setupGitUser: false + env: + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + GIT_AUTHOR_NAME: asyncapi-bot + GIT_AUTHOR_EMAIL: info@asyncapi.io + GIT_COMMITTER_NAME: asyncapi-bot + GIT_COMMITTER_EMAIL: info@asyncapi.io + - if: failure() # Only, on failure, send a message on the 94_bot-failing-ci Slack channel + name: Report workflow run status to Slack + uses: 8398a7/action-slack@v3 + with: + status: ${{ job.status }} + fields: repo,action,workflow + text: "Release workflow failed in release job" + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CI_FAIL_NOTIFY }} From 83ec053ba0ea91e44888b7ed2a5c2372f8c0ffec Mon Sep 17 00:00:00 2001 From: akshatnema Date: Mon, 25 Nov 2024 00:32:25 +0530 Subject: [PATCH 2/5] updated release workflow with changeset --- .github/workflows/release-with-changesets.yml | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release-with-changesets.yml b/.github/workflows/release-with-changesets.yml index 327dfd4eb40..6a16eebfce4 100644 --- a/.github/workflows/release-with-changesets.yml +++ b/.github/workflows/release-with-changesets.yml @@ -108,13 +108,33 @@ jobs: shell: bash # This step can be removed once the issue is fixed in the changeset package. run: npm install @changesets/changelog-git@0.2.0 + - if: steps.packagejson.outputs.exists == 'true' + name: Get version from the changeset + uses: changesets/action@v1 + id: get-version + with: + version: npx -p @changesets/cli@2.27.7 changeset version + - if: steps.packagejson.outputs.exists == 'true' + name: Update version inside action.yml + uses: actions/github-script@v6 + with: + script: | + const fs = require('fs'); + const path = require('path'); + + const templatePath = path.resolve(__dirname, '../../', 'action-template.yml'); + const outputPath = path.resolve(__dirname, '../../', 'action.yml'); + + const updatedContent = templateContent.replace(/\${ version }/g, '${{ steps.get-version.outputs.version }}'); + fs.writeFileSync(outputPath, updatedContent, 'utf8'); + console.log(`Updated action.yml with version ${{ steps.get-version.outputs.version }}`); + - if: steps.packagejson.outputs.exists == 'true' name: Publish to any of NPM, Github, and Docker Hub #this step has 2 goals, it is either identifying that there is changeset file created and then this action creates a PR with version bump that will trigger release - or if it sees there is no changeset, and there are versions changes in package.json files, it publish new versions to NPM is they are not there yet uses: changesets/action@v1 id: release with: - version: npx -p @changesets/cli@2.27.7 changeset version commit: "chore(release): release and bump versions of packages" title: "chore(release): release and bump versions of packages" publish: npx -p @changesets/cli@2.27.7 changeset publish From 1f41af92ffeaae0adfd5c009a6faa887510c884e Mon Sep 17 00:00:00 2001 From: akshatnema Date: Sat, 7 Dec 2024 01:11:55 +0530 Subject: [PATCH 3/5] updated release workflow with changeset --- .github/workflows/release-with-changesets.yml | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release-with-changesets.yml b/.github/workflows/release-with-changesets.yml index 6a16eebfce4..45498ebd033 100644 --- a/.github/workflows/release-with-changesets.yml +++ b/.github/workflows/release-with-changesets.yml @@ -109,11 +109,24 @@ jobs: # This step can be removed once the issue is fixed in the changeset package. run: npm install @changesets/changelog-git@0.2.0 - if: steps.packagejson.outputs.exists == 'true' - name: Get version from the changeset + name: Get version update from the changeset uses: changesets/action@v1 - id: get-version with: version: npx -p @changesets/cli@2.27.7 changeset version + commit: "chore(release): release and bump versions of packages" + title: "chore(release): release and bump versions of packages" + env: + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + GIT_AUTHOR_NAME: asyncapi-bot + GIT_AUTHOR_EMAIL: info@asyncapi.io + GIT_COMMITTER_NAME: asyncapi-bot + GIT_COMMITTER_EMAIL: info@asyncapi.io + + - if: steps.packagejson.outputs.exists == 'true' + name: Get version from package.json + id: get-version + run: echo ::set-output name=version::$(node -p "require('./package.json').version") + - if: steps.packagejson.outputs.exists == 'true' name: Update version inside action.yml uses: actions/github-script@v6 @@ -122,21 +135,27 @@ jobs: const fs = require('fs'); const path = require('path'); - const templatePath = path.resolve(__dirname, '../../', 'action-template.yml'); - const outputPath = path.resolve(__dirname, '../../', 'action.yml'); + const templatePath = path.resolve('./', 'action-template.yml'); + const outputPath = path.resolve('./', 'action.yml'); + const templateContent = fs.readFileSync(templatePath, 'utf8'); const updatedContent = templateContent.replace(/\${ version }/g, '${{ steps.get-version.outputs.version }}'); + fs.writeFileSync(outputPath, updatedContent, 'utf8'); console.log(`Updated action.yml with version ${{ steps.get-version.outputs.version }}`); + - if: steps.packagejson.outputs.exists == 'true' + name: Commit changes of action.yml + run: | + git commit -am "chore(release): release and bump versions of github action docker" + git push --set-upstream origin ${GITHUB_REF#refs/heads/} || git push origin ${GITHUB_REF#refs/heads/} + - if: steps.packagejson.outputs.exists == 'true' name: Publish to any of NPM, Github, and Docker Hub #this step has 2 goals, it is either identifying that there is changeset file created and then this action creates a PR with version bump that will trigger release - or if it sees there is no changeset, and there are versions changes in package.json files, it publish new versions to NPM is they are not there yet uses: changesets/action@v1 id: release with: - commit: "chore(release): release and bump versions of packages" - title: "chore(release): release and bump versions of packages" publish: npx -p @changesets/cli@2.27.7 changeset publish setupGitUser: false env: From efbb2e9bbdaf4c395c01ba0330dfc437d8909c89 Mon Sep 17 00:00:00 2001 From: akshatnema Date: Sat, 7 Dec 2024 16:05:10 +0530 Subject: [PATCH 4/5] added Development.md for changesets config --- Development.md | 141 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 Development.md diff --git a/Development.md b/Development.md new file mode 100644 index 00000000000..a56c43aa745 --- /dev/null +++ b/Development.md @@ -0,0 +1,141 @@ +# Development guide + +This guide will help you set up the `cli` locally, run tests, and use Docker for isolated testing. + +## Getting started + +1. Fork & Clone the repository: + +First fork the repository from github and then clone it, + +```bash +git clone https://github.com/{your_username}/cli.git +cd cli +``` + +After cloning the repository, you should setup the fork properly and configure the `remote` repository as described [here](https://github.com/asyncapi/community/blob/master/git-workflow.md) + +2. Install dependencies: + +```bash +npm install +``` + +## Running tests + +### Local testing + +To run all tests locally: + +- Unit tests: `npm run test:unit` +- Github action tests: `npm run action:test` + +### Adding tests + +1. Create new test files in the appropriate directory under `test/`: + +2. Follow the existing test patterns. + +3. Run your new tests using the commands mentioned above. + +## Release process + +To release a major/minor/patch: + +### Conventional Commits: + +To maintain a clear git history of commits and easily identify what each commit changed and whether it triggered a release, we use conventional commits. The feat and fix prefixes are particularly important as they are needed to trigger changesets. Using these prefixes ensures that the changes are correctly categorized and the versioning system functions as expected. + +For Example: +``` +feat: add new feature +``` + +#### Manual + +1. Create a new release markdown file in the `.changeset` directory. The filename should indicate what the change is about. + +2. Add the following content to the file in this particular format: + + ```markdown + --- + "@package-name-1": [type] (major/minor/patch) + "@package-name-2": [type] + --- + + [Provide a brief description of the changes. For example: Added a new Release GitHub Flow to the Turborepo. No new features or bugfixes were introduced.] + ``` + + For Example: + + ```markdown + --- + "@asyncapi/generator": minor + --- + + Adding new Release Github Flow to the Turborepo. No new features or bugfixes were introduced. + + ``` + +3. Include the file in your pull request. + +#### Using CLI + +1. Create a new release markdown file using changeset CLI. Below command will trigger an interactive prompt that you can use to specify release type and affected packages. + ```cli + npx -p @changesets/cli@2.27.7 changeset + ``` + +2. Include the file in your pull request. + +> [!TIP] +> For more detailed instructions, you can refer to the official documentation for creating a changeset: +[Adding a changeset](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md) + +### Release Flow: + +1. **Add a Changeset**: + - When you make changes that need to be released, create a markdown file in the `.changeset` directory stating the package name and level of change (major/minor/patch). + +2. **Open a Pull Request**: + - Push your changes and open a Pull Request (PR). After the PR is merged the changeset file helps communicate the type of changes (major, minor, patch). + +3. **CI Processes Changeset**: + - After PR is merged, a dedicated GitHub Actions release workflow runs using changeset action, + + - This action reads the markdown files in the `.changeset` folder and creates a PR with the updated version of the package and removes the markdown file. For example: + + Before: + ```json + "name": "@asyncapi/generator", + "version": "2.0.1", + ``` + + After: + ```json + "name": "@asyncapi/generator", + "version": "3.0.1", + ``` + + - The new PR will also contain the description from the markdown files, + + - AsyncAPI bot automatically merge such release PR. + +4. **Release the Package**: + + - After the PR is merged, the CI/CD pipeline triggers again. The `changesets/action` step identifies that the PR was created by itself. It then verifies if the current version of the package is greater than the previously released version. If a difference is detected, it executes the publish command to release the updated package. + +## Additional commands + +- Lint the code: `npm run lint` +- Build Docker image: `npm run docker:build` + +## Troubleshooting + +If you encounter any issues during development or testing, please check the following: + +1. Ensure you're using the correct Node.js version (18.12.0 or higher) and npm version (8.19.0 or higher). +2. Clear the `node_modules` directory and reinstall dependencies if you encounter unexpected behavior. +3. For Docker-related issues, make sure Docker is running and you have sufficient permissions. + +If problems persist, please open an issue on the GitHub repository. From eeaae26a905e63e58f20666b0495b040202e4768 Mon Sep 17 00:00:00 2001 From: akshatnema Date: Sat, 7 Dec 2024 16:40:39 +0530 Subject: [PATCH 5/5] updated Development.md file --- Development.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Development.md b/Development.md index a56c43aa745..da228de676c 100644 --- a/Development.md +++ b/Development.md @@ -70,7 +70,7 @@ feat: add new feature ```markdown --- - "@asyncapi/generator": minor + "@asyncapi/cli": minor --- Adding new Release Github Flow to the Turborepo. No new features or bugfixes were introduced. @@ -107,13 +107,13 @@ feat: add new feature Before: ```json - "name": "@asyncapi/generator", + "name": "@asyncapi/cli", "version": "2.0.1", ``` After: ```json - "name": "@asyncapi/generator", + "name": "@asyncapi/cli", "version": "3.0.1", ```