From ba45e197c028f66bb0c6164a54421f157b70ccbe Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Thu, 23 Jun 2022 10:25:46 +0200 Subject: [PATCH 1/8] chore: update `next-spec` branch with latest changes from `master` (#810) --- .all-contributorsrc | 58 ++++++++- .github/scripts/remove-toc.js | 4 +- .github/workflows/automerge-orphans.yml | 1 + .github/workflows/autoupdate.yml | 3 +- .github/workflows/help-command.yml | 2 +- .github/workflows/link-check-cron.yml | 1 + .github/workflows/new-spec-release.yml | 10 +- .github/workflows/stale-issues-prs.yml | 1 + .github/workflows/update-spec.yaml | 2 +- .releaserc | 4 +- CODE_OF_CONDUCT.md | 46 +++++++ README.md | 11 +- RELEASE_PROCESS.md | 141 +++++++++++---------- assets/release_process/create_branch.png | Bin 118110 -> 0 bytes examples/gitter-streaming.yml | 2 +- examples/rpc-client.yml | 2 +- examples/rpc-server.yml | 2 +- examples/slack-rtm.yml | 2 +- examples/social-media/common/messages.yaml | 4 +- mlc_config.json | 19 +++ spec/asyncapi.md | 18 +-- 21 files changed, 232 insertions(+), 101 deletions(-) create mode 100644 CODE_OF_CONDUCT.md delete mode 100644 assets/release_process/create_branch.png create mode 100644 mlc_config.json diff --git a/.all-contributorsrc b/.all-contributorsrc index 6d6834d7..c1cb2a3a 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -145,7 +145,9 @@ "profile": "https://waleedashraf.me/", "contributions": [ "talk", - "ideas" + "ideas", + "doc", + "example" ] }, { @@ -215,7 +217,12 @@ "profile": "https://github.com/magicmatatjahu", "contributions": [ "review", - "ideas" + "ideas", + "question", + "bug", + "doc", + "example", + "maintenance" ] }, { @@ -224,7 +231,11 @@ "avatar_url": "https://avatars.githubusercontent.com/u/193286?v=4", "profile": "https://vladimirgorej.com/", "contributions": [ - "doc" + "doc", + "bug", + "example", + "ideas", + "review" ] }, { @@ -271,7 +282,12 @@ "contributions": [ "review", "ideas", - "question" + "question", + "blog", + "bug", + "doc", + "example", + "maintenance" ] }, { @@ -329,6 +345,40 @@ "contributions": [ "doc" ] + }, + { + "login": "danielkocot", + "name": "Daniel Kocot", + "avatar_url": "https://avatars.githubusercontent.com/u/466609?v=4", + "profile": "https://danielkocot.github.io/", + "contributions": [ + "doc", + "example", + "ideas" + ] + }, + { + "login": "sekharbans-ebay", + "name": "sekharbans-ebay", + "avatar_url": "https://avatars.githubusercontent.com/u/66145510?v=4", + "profile": "https://github.com/sekharbans-ebay", + "contributions": [ + "doc", + "example", + "ideas" + ] + }, + { + "login": "damaru-inc", + "name": "Michael Davis", + "avatar_url": "https://avatars.githubusercontent.com/u/3926925?v=4", + "profile": "http://www.damaru.com/", + "contributions": [ + "bug", + "doc", + "example", + "ideas" + ] } ], "commitConvention": "none" diff --git a/.github/scripts/remove-toc.js b/.github/scripts/remove-toc.js index b1305b21..29adb588 100644 --- a/.github/scripts/remove-toc.js +++ b/.github/scripts/remove-toc.js @@ -9,7 +9,7 @@ module.exports = (givenSpec) => { const startingLine = "## Table of Contents\n"; const endingLine = "\n"; - const specFile = fs.readFileSync(`./website/pages/docs/specifications/${givenSpec}.md`); + const specFile = fs.readFileSync(`./website/pages/docs/reference/specification/${givenSpec}.md`); const startingIndex = specFile.indexOf(startingLine); const endingIndex = specFile.indexOf(endingLine); @@ -21,5 +21,5 @@ module.exports = (givenSpec) => { const firstHalf = specFile.slice(0, startingIndex); const secondHalf = specFile.slice(endingIndex + endingLine.length); const specWithoutToc = `${firstHalf}${secondHalf}`; - fs.writeFileSync(`./website/pages/docs/specifications/${givenSpec}.md`, specWithoutToc); + fs.writeFileSync(`./website/pages/docs/reference/specification/${givenSpec}.md`, specWithoutToc); } diff --git a/.github/workflows/automerge-orphans.yml b/.github/workflows/automerge-orphans.yml index 5e2ff6ed..20322ecb 100644 --- a/.github/workflows/automerge-orphans.yml +++ b/.github/workflows/automerge-orphans.yml @@ -9,6 +9,7 @@ on: jobs: identify-orphans: + if: startsWith(github.repository, 'asyncapi/') name: Find orphans and notify runs-on: ubuntu-latest steps: diff --git a/.github/workflows/autoupdate.yml b/.github/workflows/autoupdate.yml index f23ec3b8..ad8e0198 100644 --- a/.github/workflows/autoupdate.yml +++ b/.github/workflows/autoupdate.yml @@ -20,13 +20,14 @@ on: jobs: autoupdate-for-bot: + if: startsWith(github.repository, 'asyncapi/') name: Autoupdate autoapproved PR created in the upstream runs-on: ubuntu-latest steps: - name: Autoupdating uses: docker://chinthakagodawita/autoupdate-action:v1 env: - GITHUB_TOKEN: '${{ secrets.GH_TOKEN }}' + GITHUB_TOKEN: '${{ secrets.GH_TOKEN_BOT_EVE }}' PR_FILTER: "labelled" PR_LABELS: "autoupdate" PR_READY_STATE: "ready_for_review" diff --git a/.github/workflows/help-command.yml b/.github/workflows/help-command.yml index 69163816..03f891eb 100644 --- a/.github/workflows/help-command.yml +++ b/.github/workflows/help-command.yml @@ -25,7 +25,7 @@ jobs: - `/ready-to-merge` or `/rtm` - This comment will trigger automerge of PR in case all required checks are green, approvals in place and do-not-merge label is not added - `/do-not-merge` or `/dnm` - This comment will block automerging even if all conditions are met and ready-to-merge label is added - - `/autoupdate` or `/au` - This comment will add `autoupdate` label to the PR and keeps your PR up-to-date to the target branch's future changes. Unless there is a merge conflict. + - `/autoupdate` or `/au` - This comment will add `autoupdate` label to the PR and keeps your PR up-to-date to the target branch's future changes. Unless there is a merge conflict or it is a draft PR. create_help_comment_issue: if: ${{ !github.event.issue.pull_request && contains(github.event.comment.body, '/help') && github.actor != 'asyncapi-bot' }} runs-on: ubuntu-latest diff --git a/.github/workflows/link-check-cron.yml b/.github/workflows/link-check-cron.yml index cfc2cf01..44e1a5cb 100644 --- a/.github/workflows/link-check-cron.yml +++ b/.github/workflows/link-check-cron.yml @@ -11,6 +11,7 @@ on: jobs: External-link-validation-weekly: + if: startsWith(github.repository, 'asyncapi/') runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/new-spec-release.yml b/.github/workflows/new-spec-release.yml index 8eef2276..eadf1fda 100644 --- a/.github/workflows/new-spec-release.yml +++ b/.github/workflows/new-spec-release.yml @@ -38,20 +38,20 @@ jobs: script: | const fs = require("fs"); - const specFiles = fs.readdirSync("./website/pages/docs/specifications"); + const specFiles = fs.readdirSync("./website/pages/docs/reference/specification"); const nextRelease = `${{github.event.release.tag_name}}`; const prefixRelease = nextRelease.split("-")[0]; for (const filename of specFiles) { if (filename.startsWith(prefixRelease)) { - fs.unlinkSync(`./website/pages/docs/specifications/${filename}`); + fs.unlinkSync(`./website/pages/docs/reference/specification/${filename}`); } } - name: Copy Spec file from Current Repo to Another working-directory: ./website run: | - cp ../spec/spec/asyncapi.md ./pages/docs/specifications/${{github.event.release.tag_name}}.md + cp ../spec/spec/asyncapi.md ./pages/docs/reference/specification/${{github.event.release.tag_name}}.md - name: Remove Table of Contents from Spec uses: actions/github-script@v4 with: @@ -71,7 +71,7 @@ jobs: const endingLine = "# LATEST-SPEC-REDIRECTION:END"; const releaseVersion = `${{github.event.release.tag_name}}`; - const redirectLine = `/docs/specifications/latest /docs/specifications/${releaseVersion} 302!\n`; + const redirectLine = `/docs/reference/specification/latest /docs/reference/specification/${releaseVersion} 302!\n`; const redirectFile = fs.readFileSync("./website/public/_redirects", "utf-8"); @@ -139,7 +139,7 @@ jobs: const releaseVersionWithoutV = releaseVersion.slice(1); - const redirectLine = `/docs/specifications/${releaseVersionWithoutV} /docs/specifications/${releaseVersion} 302!\n`; + const redirectLine = `/docs/reference/specification/${releaseVersionWithoutV} /docs/reference/specification/${releaseVersion} 302!\n`; const redirectFile = fs.readFileSync("./website/public/_redirects", "utf-8"); diff --git a/.github/workflows/stale-issues-prs.yml b/.github/workflows/stale-issues-prs.yml index 76673183..c1c0c61d 100644 --- a/.github/workflows/stale-issues-prs.yml +++ b/.github/workflows/stale-issues-prs.yml @@ -9,6 +9,7 @@ on: jobs: stale: + if: startsWith(github.repository, 'asyncapi/') name: Mark issue or PR as stale runs-on: ubuntu-latest steps: diff --git a/.github/workflows/update-spec.yaml b/.github/workflows/update-spec.yaml index 0dfa85ed..528a66e5 100644 --- a/.github/workflows/update-spec.yaml +++ b/.github/workflows/update-spec.yaml @@ -41,7 +41,7 @@ jobs: - name: Copy Spec file from Current Repo to Another working-directory: ./website run: | - cp ../spec/spec/asyncapi.md ./pages/docs/specifications/${{ steps.latest_version.outputs.latest_tag }}.md + cp ../spec/spec/asyncapi.md ./pages/docs/reference/specification/${{ steps.latest_version.outputs.latest_tag }}.md - name: Remove Table of Contents from Spec uses: actions/github-script@v4 with: diff --git a/.releaserc b/.releaserc index 80428b1a..fa26f7f7 100644 --- a/.releaserc +++ b/.releaserc @@ -1,7 +1,9 @@ --- branches: - master -- name: 2022-04-release +- name: next-spec + prerelease: true +- name: next-major-spec prerelease: true plugins: - - "@semantic-release/commit-analyzer" diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..638f7334 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at fmvilas@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/README.md b/README.md index 8c414200..f1f2b087 100644 --- a/README.md +++ b/README.md @@ -104,20 +104,20 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Jonas Lagoni

🐛 📖 🤔 💬 👀 💡 -
Waleed Ashraf

📢 🤔 +
Waleed Ashraf

📢 🤔 📖 💡
Andrzej Jarzyna

📢
Emmelyn Wang

📝 🤔 📖 📢
Marc DiPasquale

📝 📢 👀 🐛 🤔 📹
Gerald Loeffler

📖 🐛 🤔
Dale Lane

📝 🤔 📹 📢 📖 -
Maciej Urbańczyk

👀 🤔 -
Vladimir Gorej

📖 +
Maciej Urbańczyk

👀 🤔 💬 🐛 📖 💡 🚧 +
Vladimir Gorej

📖 🐛 💡 🤔 👀
Lorna Jane Mitchell

📢 🤔
Laurent Broudoux

📖 📝 📢 💡 🤔 👀
Jesse Menning

📝 📢 👀 🤔 -
Sergio Moya

👀 🤔 💬 +
Sergio Moya

👀 🤔 💬 📝 🐛 📖 💡 🚧
Alexander Balogh

📖 🐛
Khuda Dad Nomani

💡 🐛
Aaron Korver

📖 @@ -126,6 +126,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Muhammad Rafly Andrianza

📖 +
Daniel Kocot

📖 💡 🤔 +
sekharbans-ebay

📖 💡 🤔 +
Michael Davis

🐛 📖 💡 🤔 diff --git a/RELEASE_PROCESS.md b/RELEASE_PROCESS.md index 07547270..f2bef981 100644 --- a/RELEASE_PROCESS.md +++ b/RELEASE_PROCESS.md @@ -84,33 +84,29 @@ A [template for a new release issue](https://github.com/asyncapi/spec/blob/maste An example is the [release issue for the 2.3.0](https://github.com/asyncapi/spec/issues/675) release. -### Step 3 - create release branches +### Step 3 - update release branches -Release branches must have a year and a month of the release as prefix: {YEAR_OF_RELEASE}-{MONTH_OF_RELEASE}-release. +Release branches should be present in the following repositories: -For example, a release created in September 2021 has a `2021-09-release` release branch. - -This image shows part of the GitHub UI that shows how you can create a new branch using default branch as a base. - -At the beginning of the release cycle, we need to have a new release branch created in the following repositories: - [spec](https://github.com/asyncapi/spec) where contributor works with the specification file, - [spec-json-schemas](https://github.com/asyncapi/spec-json-schemas) where contributor pushes changes to JSON Schema of the spec, - [parser-js](https://github.com/asyncapi/parser-js) where contributor makes necessary changes in the JavaScript Parser. + +Depending on the type of release you are working on, you should use one branch or another: -The [release coordinator](#%22release-coordinator%22) should decide what the branch name needs to be, and contact the [code owners](#code-owners) for each repository to ask them to create the branches for them. - - -### Step 4 - update release branches +- `next-spec`: for releasing minor versions. For example, `2.3.0` to `2.4.0`. +- `next-major-spec`: for releasing major versions. For example, `2.4.0` to `3.0.0`. -Once [release branches are created](#step-3---create-release-branches), there are some initial changes that need to be made. +Once you know which branch you should use, there are some initial changes that need to be made. The process for doing this is the same for each of these: -- the [release coordinator](#%22release-coordinator%22) should create a fork of the relevant repository for these changes +- the [release coordinator](#%22release-coordinator%22) should create a fork, if not created yet, of the relevant repository for these changes. +- the [release coordinator](#%22release-coordinator%22) should ensure the chosen **release branch** is up-to-date with the **default branch** (normally `master`) before adding any changes. - the commit message for the change should start with `chore:` -- the change should be contributed in a pull request targeting the [release branch](#step-3---create-release-branches) +- the change should be contributed in a pull request targeting the chosen **release branch**. - the [release coordinator](#%22release-coordinator%22) will need to ask the [code owners](#code-owners) for the relevant repository to approve and merge this pull request -#### Step 4.1 - Update version numbers in official examples +#### Step 3.1 - Update version numbers in official examples Repository: [spec](https://github.com/asyncapi/spec) Examples are located in the `examples/` folder in the [spec](https://github.com/asyncapi/spec) repository. They should all be updated to the new version number. @@ -119,7 +115,7 @@ An example of doing this is: - this [commit from the 2.3.0 release](https://github.com/dalelane/spec/commit/8c521539cd875470ea8e89cf3ab7ffd81be64788) - this [pull request from the 2.3.0 release](https://github.com/asyncapi/spec/pull/676) -#### Step 4.2 - Update version number in the spec +#### Step 3.2 - Update version number in the spec Repository: [spec](https://github.com/asyncapi/spec) References to the latest version in `spec/asyncapi.md` should be updated to the new version number. @@ -128,24 +124,24 @@ Examples of doing this are: - this [commit from the 2.3.0 release](https://github.com/asyncapi/spec/commit/1f29d803ca801756d4ea3f676bcf7e7751478de6) - this [commit from the 2.3.0 release](https://github.com/asyncapi/spec/commit/7f827a880fa3ddcbc9a39d50e41502bc450443bc) -#### Step 4.3 - Add new reference to the latest spec version in README +#### Step 3.3 - Add new reference to the latest spec version in README The new release should be listed in the [README.md](README.md) file and marked as `(latest)`. An example of doing this is: - this [commit from the 2.3.0 release](https://github.com/asyncapi/spec/pull/710/commits/22ba6c433ddbeeeda38f5aed55708826da62cf70) -#### Step 4.4 - Create a new JSON schema file for the new version +#### Step 3.4 - Create a new JSON schema file for the new version Repository: [spec-json-schemas](https://github.com/asyncapi/spec-json-schemas) -The new file should be created in the `schemas/` folder in the [spec-json-schemas](https://github.com/asyncapi/spec-json-schemas) repository. +To create a new version, please read [Creating a new version](https://github.com/asyncapi/spec-json-schemas#creating-a-new-version). It should be named with the version of the new release, and a link should be added to the `index.js` file (in the same repository). An example of doing this is: -- this [commit from the 2.3.0 release](https://github.com/dalelane/spec-json-schemas/commit/9cff7798ac42f609927e1cb9e532ff16d360ab99) -- this [pull request from the 2.3.0 release](https://github.com/asyncapi/spec-json-schemas/pull/139) +- this [commit from the 3.0.0 release](https://github.com/asyncapi/spec-json-schemas/pull/221/files) +- this [pull request from the 3.0.0 release](https://github.com/asyncapi/spec-json-schemas/pull/221) -#### Step 4.5 - Update the list of AsyncAPI schema MIME types with the new version +#### Step 3.5 - Update the list of AsyncAPI schema MIME types with the new version Repository: [parser-js](https://github.com/asyncapi/parser-js) The file to be updated is `lib/asyncapiSchemaFormatParser.js` in the [parser-js](https://github.com/asyncapi/parser-js) repository. @@ -156,35 +152,7 @@ An example of doing this is: - this [pull request from the 2.3.0 release](https://github.com/asyncapi/parser-js/pull/426) -### Step 5 - update default branches - -Once [release branches have been updated](#step-4---update-release-branches), the default (e.g. "master") branches should be updated to identify the new release branch. - -The process for doing this is the same for each of these: -- the [release coordinator](#%22release-coordinator%22) should create a fork of the relevant repository for these changes (_this can be the same fork as used for updating the release branches_) -- the commit message for the change should start with `chore:` -- the change should be contributed in a pull request targeting the **default branch** (normally `master`) -- the [release coordinator](#%22release-coordinator%22) will need to ask the [code owners](#code-owners) for the relevant repository to approve and merge this pull request - -#### Update package.json files -There are **two** repositories where `package.json` files need to be updated. In both repositories, the release branch name needs to be updated in the list of branches under `.release.branches`. - -- [parser-js](https://github.com/asyncapi/parser-js/blob/master/package.json#L90-L93) -- [spec-json-schemas](https://github.com/asyncapi/spec-json-schemas/blob/master/package.json#L48-L51) - -Examples of doing this are: -- this [commit from the 2.3.0 release for parser-js](https://github.com/dalelane/parser-js/commit/1d9f9ed52718269ffbce4d32bd4635c690371f80) -- this [commit from the 2.3.0 release for spec-json-schemas](https://github.com/dalelane/spec-json-schemas/commit/8a4b94aaf86240a6ca2aeb7ce3cc515bad283a2d) - - -#### Update .releaserc file -The release branch name needs to be updated in the `.releaserc` file in the [spec](https://github.com/asyncapi/spec) repository needs. - -An example of doing this is: -- this [commit from the 2.3.0 release](https://github.com/dalelane/spec/commit/210f89adc74f17aaf09d808b84132f232ff2e412) - - -### Step 6 - prepare announcement blog post +### Step 4 - prepare announcement blog post Each new release is announced by a blog post. You can see all of these at https://www.asyncapi.com/blog?tags=Release+Notes @@ -194,7 +162,7 @@ The steps to follow for this are: - Create a fork of the [website](https://github.com/asyncapi/website) repository - Create a new file at `pages/blog/release-notes-X.X.X.md` (replacing `X.X.X` with the version number for the release) - Add a standard header at the top of the file (see the release notes for [2.2.0](https://raw.githubusercontent.com/asyncapi/website/master/pages/blog/release-notes-2.2.0.md) and [2.3.0](https://raw.githubusercontent.com/asyncapi/website/master/pages/blog/release-notes-2.3.0.md) for examples) -- Add a (webp format) cover image to the `public/img/posts/release-notes-X.X.X/` folder, and update the `cover` attribute of the blog post header with it. (**Make sure to attribute the image correctly** - unsplash.com is a good source of free images for this). See [this commit from the 2.3.0 release](4050ca0540684f5188300e0c27efc713a6ba1ec2) for an example of doing this. +- Add a (webp format) cover image to the `public/img/posts/release-notes-X.X.X/` folder, and update the `cover` attribute of the blog post header with it. (**Make sure to attribute the image correctly** - unsplash.com is a good source of free images for this). See [this commit from the 2.3.0 release](https://github.com/asyncapi/website/pull/512/commits/4050ca0540684f5188300e0c27efc713a6ba1ec2) for an example of doing this. - Add a (webp format) profile picture of the release coordinator to the `public/img/avatars` folder, and update the `authors` attribute of the blog post header with it. See [this commit from the 2.3.0 release](https://github.com/asyncapi/website/pull/512/commits/006f7df26b0d0803ed2e1dd6b8004dfdaec15617) for an example of doing this. - Open a **draft** pull request against the [website](https://github.com/asyncapi/website/) repository. Make sure the option **Allow edits and access to secrets by maintainers** is selected to enable support from maintainers. This image shows example pull request created in GitHub with release notes for AsyncAPI specification @@ -203,7 +171,7 @@ An example of doing this is: - this [pull request from the 2.3.0 release](https://github.com/asyncapi/website/pull/512) -### Step 7 - create pull requests +### Step 5 - create pull requests Pull requests should be opened for all [repositories covered by this process](#repositories). @@ -217,7 +185,7 @@ Add a **autoupdate** label to the pull request by making a comment in the PR say _Note: The automation bot will keep the release branch up to date with the latest commits from the master branch (so long as there are no conflicts)._ -### Step 8 - bring updates into release branch +### Step 6 - bring updates into release branch The [release coordinator](#%22release-coordinator%22) should help to seek out possible updates that are good candidates for including in the release. @@ -235,7 +203,7 @@ Pull requests must be: - created in all repositories specified in contribution guide -### Step 9 - update announcement blog post +### Step 7 - update announcement blog post As features are identified for inclusion in the release, the [draft announcement blog post](#step-6---prepare-announcement-blog-post) should be updated with descriptions of them. The [release cooordinator](#%22release-coordinator%22) should coordinate with the feature contributors to write a description of each change. They should be able to provide input and also be allowed to work as co-authors for the release notes post. @@ -244,7 +212,7 @@ Changes in the specification need to be well described. We need clear informatio Every feature added to the [release branch](#step-3---create-release-branches) needs to be properly described in the release notes post. -### Step 10 - prepare release notes +### Step 8 - prepare release notes In addition to the [announcement blog post](#step-9---update-announcement-blog-post), the [release coordinator](#%22release-coordinator%22) should prepare release notes for each of the [repositories covered by this process](#repositories). @@ -258,7 +226,7 @@ Examples of doing this are: - the [release notes for version 2.3.0 of spec](https://github.com/asyncapi/spec/releases/tag/v2.3.0) -### Step 11 - notify people the release is coming +### Step 9 - notify people the release is coming As the release gets closer to being ready, it is helpful to remind the community that the release is on the way. @@ -271,12 +239,12 @@ This can also be done: Including a link to the [release issue](#step-2---create-a-release-issue) is a good way to let the community see the progress that has been made so far. -### Step 12 - reviews +### Step 10 - reviews At least one [code owner](#code-owners) must approve the [release pull requests](#step-7---create-pull-requests) in all related [repositories](#repositories). -### Step 13 - release candidates +### Step 11 - release candidates Pre-release release candidates are generated automatically by the automation bot when: - a pull request with a **fix** or **feat** prefix in the title is merged into the [release branch](#step-3---create-release-branches) @@ -290,11 +258,19 @@ Release candidates will include: An example release candidate is: https://github.com/asyncapi/spec/releases/tag/v2.3.0-2022-01-release.3 - **Important:** When release candidates are created for the [spec](https://github.com/asyncapi/spec) repository, the [parser-js](https://github.com/asyncapi/parser-js) repository will need to be updated to use that release candidate. +### Step 12 - Notify code owners of critical repositories about the pre-releases + +In order to let code owners of critical repositories have enough time to work on the changes needed on tooling, the [release coordinator](#%22release-coordinator%22) should notify code owners about the pre-releases. +As per today, the following repositories are considered critical: -### Step 14 - merge the release branches +- [HTML Template](https://github.com/asyncapi/html-template) +- [JavaScript Converter](https://github.com/asyncapi/converter-js/) +- [React component](https://github.com/asyncapi/asyncapi-react/) +- [Studio](https://github.com/asyncapi/studio) + +### Step 13 - merge the release branches Once everything is ready, it is time to merge the [release branches](#step-3---create-release-branches) using the [draft pull requests prepared earlier](#step-7---create-pull-requests). @@ -309,23 +285,52 @@ First, changes are merged into the `spec` repository, then `spec-json-schemas` a Release means merge of pull requests created from a release branch against the master branch. First, changes are merged into the `spec` repository, then `spec-json-schemas` and at the end in `parser-js`. Like in the case of the merge of release candidates, a pull request in `parser-js` can be merged only if it uses the final release of the new `@asyncapi/specs` package. -### Step 15 - publish releases +### Step 14 - publish releases The [release coordinator](#%22release-coordinator%22) should ask the [code owners](#code-owners) for each repository to update the release in Github created by the automation bot, by adding the [release notes they have prepared](#step-10---prepare-release-notes). -### Step 16 - notify tool maintainers +### Step 15 - notify tool maintainers + +Our current CI/CD automation will fill PR's updating the dependencies **automatically** on all repositories after the release. +However, the [release coordinator](#%22release-coordinator%22) should notify maintainers of the dependant repositories that a new release happened, as those might want to adopt the new features. -The [release coordinator](#%22release-coordinator%22) should notify maintainers of the following repositories that the first feature is merged and that release will be produced and therefore they need to start preparing for it: +Some of the dependant repositories are: + - [Avro Schema parser](https://github.com/asyncapi/avro-schema-parser) + - [Bundler](https://github.com/asyncapi/bundler) + - [CLI](https://github.com/asyncapi/cli) + - [Cupid](https://github.com/asyncapi/cupid) + - [Dot Net NATS template](https://github.com/asyncapi/dotnet-nats-template) + - [Generator](https://github.com/asyncapi/generator) + - [Generator React SDK](https://github.com/asyncapi/generator-react-sdk) + - [Glee](https://github.com/asyncapi/glee) + - [HTML Template](https://github.com/asyncapi/html-template) + - [Java Template](https://github.com/asyncapi/java-template) - [JavaScript Converter](https://github.com/asyncapi/converter-js/) - - [Playground](https://github.com/asyncapi/playground/) - - [React component](https://github.com/asyncapi/asyncapi-react/) - [Markdown template](https://github.com/asyncapi/markdown-template) + - [Modelina](https://github.com/asyncapi/modelina) + - [NodeJS WS Template](https://github.com/asyncapi/nodejs-ws-template) + - [Optimizer](https://github.com/asyncapi/optimizer) + - [Parser Go](https://github.com/asyncapi/parser-go) + - [React component](https://github.com/asyncapi/asyncapi-react/) + - [Server API](https://github.com/asyncapi/server-api/) + - [Simulator](https://github.com/asyncapi/simulator) + - [Studio](https://github.com/asyncapi/studio) + - [TS NATS Template](https://github.com/asyncapi/ts-nats-template) + +You can use Github Code Search to find the [list of repositories depending on parser-js or the specs](https://cs.github.com/?scopeName=All+repos&scope=&q=org%3Aasyncapi+%28path%3Apackage.json+OR+go.mod%29+%22%40asyncapi%2Fparser%22+OR+%22%40asyncapi%2Fspecs%22+OR+%22github.com%2Fasyncapi%2Fspec-json-schemas%22+OR+%22github.com%2Fasyncapi%2Fparser-go%22#). +Alternatively, you can use the following GH search queries: +- [NodeJS @asyncapi/specs dependants](https://github.com/search?q=org%3Aasyncapi+in%3Afile+filename%3Apackage.json+%22%40asyncapi%2Fspecs%22) +- [NodeJS @asyncapi/parser dependants](https://github.com/search?q=org%3Aasyncapi+in%3Afile+filename%3Apackage.json+%22%40asyncapi%2Fparser%22) +- [Go github.com/asyncapi/spec-json-schemas dependants](https://github.com/search?q=org%3Aasyncapi+in%3Afile+filename%3Ago.mod+%22%40github.com%2Fasyncapi%2Fspec-json-schemas%22) +- [Go github.com/asyncapi/parser-go dependants](https://github.com/search?q=org%3Aasyncapi+in%3Afile+filename%3Ago.mod+%22%40github.com%2Fasyncapi%2Fparser-go%22) + +You can check the following [example of notification to maintainers](https://github.com/asyncapi/spec/issues/735#issuecomment-1109801674). The [release coordinator](#%22release-coordinator%22) should also make sure other maintainers from other projects under the AsyncAPI GitHub organization released their packages. -### Step 17 - notify the community +### Step 16 - notify the community Every release of the release candidate is automatically published on the AsyncAPI Twitter account and in the releases-dedicated Slack channel. @@ -334,7 +339,7 @@ If the [release coordinator](#%22release-coordinator%22) uses social networks li Feel free to use other communication channels. Make sure that as many people as possible know about the change. Feel free to contact vendors upfront or other people that are interested in changes in the specification. -### Step 18 - improve the release process +### Step 17 - improve the release process Every release identifies new issues and ways that the process can be improved. diff --git a/assets/release_process/create_branch.png b/assets/release_process/create_branch.png deleted file mode 100644 index 8c1ae686ec07ad9bcaff502db20a0c7ac42973d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 118110 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 diff --git a/examples/gitter-streaming.yml b/examples/gitter-streaming.yml index 41e6e454..2305245d 100644 --- a/examples/gitter-streaming.yml +++ b/examples/gitter-streaming.yml @@ -1,5 +1,5 @@ asyncapi: '2.4.0' -id: 'urn:com:gitter:streaming:api' +id: 'tag:stream.gitter.im,2022:api' info: title: Gitter Streaming API version: '1.0.0' diff --git a/examples/rpc-client.yml b/examples/rpc-client.yml index 92b0938e..5cbf1116 100644 --- a/examples/rpc-client.yml +++ b/examples/rpc-client.yml @@ -1,5 +1,5 @@ asyncapi: '2.4.0' -id: 'urn:rpc:example:client' +id: 'urn:example:rpcclient' defaultContentType: application/json info: diff --git a/examples/rpc-server.yml b/examples/rpc-server.yml index 09db34fb..e7103e52 100644 --- a/examples/rpc-server.yml +++ b/examples/rpc-server.yml @@ -1,5 +1,5 @@ asyncapi: '2.4.0' -id: 'urn:rpc:example:server' +id: 'urn:example:rpcserver' defaultContentType: application/json info: diff --git a/examples/slack-rtm.yml b/examples/slack-rtm.yml index 5416c168..b4bef83b 100644 --- a/examples/slack-rtm.yml +++ b/examples/slack-rtm.yml @@ -1,5 +1,5 @@ asyncapi: '2.4.0' -id: 'urn:com:slack:rtm:api' +id: 'wss://wss-primary.slack.com/websocket' info: title: Slack Real Time Messaging API version: '1.0.0' diff --git a/examples/social-media/common/messages.yaml b/examples/social-media/common/messages.yaml index 33825171..a4b267ac 100644 --- a/examples/social-media/common/messages.yaml +++ b/examples/social-media/common/messages.yaml @@ -9,8 +9,8 @@ likeComment: commentChanged: description: Message that is being sent when a comment have been updated. payload: - $ref: './schemas.yaml#/commentChanged' + $ref: './schemas.yaml#/commentChangedPayload' updateCommentLikes: description: Message that is being sent when a comment have been updated. payload: - $ref: './schemas.yaml#/updateCommentLikesPayload' \ No newline at end of file + $ref: './schemas.yaml#/updateCommentLikesPayload' diff --git a/mlc_config.json b/mlc_config.json new file mode 100644 index 00000000..01833db7 --- /dev/null +++ b/mlc_config.json @@ -0,0 +1,19 @@ +{ + "ignorePatterns": [ + { + "pattern": "^https://github.com/asyncapi/spec/tree/BRANCH_NAME" + }, + { + "pattern": "^https://github.com/asyncapi/spec-json-schemas/tree/BRANCH_NAME" + }, + { + "pattern": "^https://github.com/asyncapi/parser-js/tree/BRANCH_NAME" + }, + { + "pattern": "^https://github.com/asyncapi/website/pull/PULLREQUEST" + }, + { + "pattern": "^https://github.com/asyncapi/spec/blob/.*.md$" + } + ] +} diff --git a/spec/asyncapi.md b/spec/asyncapi.md index a0ed1599..efe90d81 100644 --- a/spec/asyncapi.md +++ b/spec/asyncapi.md @@ -188,12 +188,12 @@ It is RECOMMENDED to use a [URN](https://tools.ietf.org/html/rfc8141) to globall ```json { - "id": "urn:com:smartylighting:streetlights:server" + "id": "urn:example:com:smartylighting:streetlights:server" } ``` ```yaml -id: 'urn:com:smartylighting:streetlights:server' +id: 'urn:example:com:smartylighting:streetlights:server' ``` ```json @@ -1895,10 +1895,12 @@ additionalProperties: "required": [ "name" ], - "example": { - "name": "Puma", - "id": 1 - } + "examples": [ + { + "name": "Puma", + "id": 1 + } + ] } ``` @@ -1912,8 +1914,8 @@ properties: type: string required: - name -example: - name: Puma +examples: +- name: Puma id: 1 ``` From 03f80ad4c22cc44809bb03aab5c25e7d1b265a3d Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Thu, 23 Jun 2022 17:51:10 +0200 Subject: [PATCH 2/8] chore: set 2.5.0 as the latest version of the spec (#808) --- README.md | 3 ++- examples/anyof.yml | 2 +- examples/application-headers.yml | 2 +- examples/correlation-id.yml | 2 +- examples/gitter-streaming.yml | 2 +- examples/mercure.yml | 2 +- examples/not.yml | 2 +- examples/oneof.yml | 2 +- examples/operation-security.yml | 2 +- examples/rpc-client.yml | 2 +- examples/rpc-server.yml | 2 +- examples/simple.yml | 2 +- examples/slack-rtm.yml | 2 +- examples/streetlights-kafka.yml | 2 +- examples/streetlights-mqtt.yml | 2 +- examples/streetlights-operation-security.yml | 2 +- examples/websocket-gemini.yml | 2 +- spec/asyncapi.md | 4 ++-- 18 files changed, 20 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index f1f2b087..2de11dbb 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,8 @@ The latest draft specification can be found at [spec/asyncapi.md](./spec/asyncapi.md) which tracks the latest commit to the master branch in this repository. -- [Version 2.4.0](https://github.com/asyncapi/spec/blob/v2.4.0/spec/asyncapi.md) (latest) +- [Version 2.5.0](https://github.com/asyncapi/spec/blob/v2.5.0/spec/asyncapi.md) (latest) +- [Version 2.4.0](https://github.com/asyncapi/spec/blob/v2.4.0/spec/asyncapi.md) - [Version 2.3.0](https://github.com/asyncapi/spec/blob/v2.3.0/spec/asyncapi.md) - [Version 2.2.0](https://github.com/asyncapi/spec/blob/v2.2.0/spec/asyncapi.md) - [Version 2.1.0](https://github.com/asyncapi/spec/blob/v2.1.0/spec/asyncapi.md) diff --git a/examples/anyof.yml b/examples/anyof.yml index b1779975..a73ac409 100644 --- a/examples/anyof.yml +++ b/examples/anyof.yml @@ -1,4 +1,4 @@ -asyncapi: '2.4.0' +asyncapi: '2.5.0' info: title: AnyOf example version: '1.0.0' diff --git a/examples/application-headers.yml b/examples/application-headers.yml index c66bcef3..0ebe339d 100644 --- a/examples/application-headers.yml +++ b/examples/application-headers.yml @@ -1,4 +1,4 @@ -asyncapi: '2.4.0' +asyncapi: '2.5.0' info: title: Application Headers example version: '1.0.0' diff --git a/examples/correlation-id.yml b/examples/correlation-id.yml index f501c59a..33bb2770 100644 --- a/examples/correlation-id.yml +++ b/examples/correlation-id.yml @@ -1,4 +1,4 @@ -asyncapi: '2.4.0' +asyncapi: '2.5.0' info: title: Correlation ID Example version: '1.0.0' diff --git a/examples/gitter-streaming.yml b/examples/gitter-streaming.yml index 2305245d..1d53a01b 100644 --- a/examples/gitter-streaming.yml +++ b/examples/gitter-streaming.yml @@ -1,4 +1,4 @@ -asyncapi: '2.4.0' +asyncapi: '2.5.0' id: 'tag:stream.gitter.im,2022:api' info: title: Gitter Streaming API diff --git a/examples/mercure.yml b/examples/mercure.yml index 32f2a4ad..388f4dbc 100644 --- a/examples/mercure.yml +++ b/examples/mercure.yml @@ -1,4 +1,4 @@ -asyncapi: '2.4.0' +asyncapi: '2.5.0' info: title: Mercure Hub Example version: '1.0.0' diff --git a/examples/not.yml b/examples/not.yml index 957add7d..0b4e2e71 100644 --- a/examples/not.yml +++ b/examples/not.yml @@ -1,4 +1,4 @@ -asyncapi: '2.4.0' +asyncapi: '2.5.0' info: title: Not example version: '1.0.0' diff --git a/examples/oneof.yml b/examples/oneof.yml index d0697f49..6bc4c92e 100644 --- a/examples/oneof.yml +++ b/examples/oneof.yml @@ -1,4 +1,4 @@ -asyncapi: '2.4.0' +asyncapi: '2.5.0' info: title: OneOf example version: '1.0.0' diff --git a/examples/operation-security.yml b/examples/operation-security.yml index 0ee3c26c..f853072b 100644 --- a/examples/operation-security.yml +++ b/examples/operation-security.yml @@ -1,4 +1,4 @@ -asyncapi: 2.4.0 +asyncapi: 2.5.0 info: title: Notifications version: 1.0.0 diff --git a/examples/rpc-client.yml b/examples/rpc-client.yml index 5cbf1116..68f5d801 100644 --- a/examples/rpc-client.yml +++ b/examples/rpc-client.yml @@ -1,4 +1,4 @@ -asyncapi: '2.4.0' +asyncapi: '2.5.0' id: 'urn:example:rpcclient' defaultContentType: application/json diff --git a/examples/rpc-server.yml b/examples/rpc-server.yml index e7103e52..de4896eb 100644 --- a/examples/rpc-server.yml +++ b/examples/rpc-server.yml @@ -1,4 +1,4 @@ -asyncapi: '2.4.0' +asyncapi: '2.5.0' id: 'urn:example:rpcserver' defaultContentType: application/json diff --git a/examples/simple.yml b/examples/simple.yml index cb852949..329d5073 100644 --- a/examples/simple.yml +++ b/examples/simple.yml @@ -1,4 +1,4 @@ -asyncapi: '2.4.0' +asyncapi: '2.5.0' info: title: Account Service version: 1.0.0 diff --git a/examples/slack-rtm.yml b/examples/slack-rtm.yml index b4bef83b..20234a2b 100644 --- a/examples/slack-rtm.yml +++ b/examples/slack-rtm.yml @@ -1,4 +1,4 @@ -asyncapi: '2.4.0' +asyncapi: '2.5.0' id: 'wss://wss-primary.slack.com/websocket' info: title: Slack Real Time Messaging API diff --git a/examples/streetlights-kafka.yml b/examples/streetlights-kafka.yml index 7bef1a59..22119954 100644 --- a/examples/streetlights-kafka.yml +++ b/examples/streetlights-kafka.yml @@ -1,4 +1,4 @@ -asyncapi: '2.4.0' +asyncapi: '2.5.0' info: title: Streetlights Kafka API version: '1.0.0' diff --git a/examples/streetlights-mqtt.yml b/examples/streetlights-mqtt.yml index 5a000bd0..450ec442 100644 --- a/examples/streetlights-mqtt.yml +++ b/examples/streetlights-mqtt.yml @@ -1,4 +1,4 @@ -asyncapi: '2.4.0' +asyncapi: '2.5.0' info: title: Streetlights MQTT API version: '1.0.0' diff --git a/examples/streetlights-operation-security.yml b/examples/streetlights-operation-security.yml index d75d9a37..faf12276 100644 --- a/examples/streetlights-operation-security.yml +++ b/examples/streetlights-operation-security.yml @@ -1,4 +1,4 @@ -asyncapi: '2.4.0' +asyncapi: '2.5.0' info: title: Streetlights Kafka API version: '1.0.0' diff --git a/examples/websocket-gemini.yml b/examples/websocket-gemini.yml index b4fc46df..75af8d4d 100644 --- a/examples/websocket-gemini.yml +++ b/examples/websocket-gemini.yml @@ -12,7 +12,7 @@ # - Live stream about topics mentioned in part 1 and 2 articles: https://www.youtube.com/watch?v=8tFBcf31e_c # -asyncapi: '2.4.0' +asyncapi: '2.5.0' # # Overal information for users of the application diff --git a/spec/asyncapi.md b/spec/asyncapi.md index efe90d81..822cba5d 100644 --- a/spec/asyncapi.md +++ b/spec/asyncapi.md @@ -4,7 +4,7 @@ Part of this content has been taken from the great work done by the folks at the [OpenAPI Initiative](https://openapis.org). Mainly because **it's a great work** and we want to keep as much compatibility as possible with the [OpenAPI Specification](https://github.com/OAI/OpenAPI-Specification). -#### Version 2.4.0 +#### Version 2.5.0 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt). @@ -1106,7 +1106,7 @@ The following table contains a set of values that every implementation MUST supp Name | Allowed values | Notes ---|:---:|--- -[AsyncAPI 2.4.0 Schema Object](#schemaObject) | `application/vnd.aai.asyncapi;version=2.4.0`, `application/vnd.aai.asyncapi+json;version=2.4.0`, `application/vnd.aai.asyncapi+yaml;version=2.4.0` | This is the default when a `schemaFormat` is not provided. +[AsyncAPI 2.5.0 Schema Object](#schemaObject) | `application/vnd.aai.asyncapi;version=2.5.0`, `application/vnd.aai.asyncapi+json;version=2.5.0`, `application/vnd.aai.asyncapi+yaml;version=2.5.0` | This is the default when a `schemaFormat` is not provided. [JSON Schema Draft 07](https://json-schema.org/specification-links.html#draft-7) | `application/schema+json;version=draft-07`, `application/schema+yaml;version=draft-07` | The following table contains a set of values that every implementation is RECOMMENDED to support. From 250e9c984793e86f2becea818e5440df56a49263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Gorej?= Date: Wed, 14 Sep 2022 18:33:32 +0200 Subject: [PATCH 3/8] chore: update next-spec branch with master changes (#831) --- .github/ISSUE_TEMPLATE/release.md | 18 +++++ .github/workflows/link-check-cron.yml | 2 +- .github/workflows/stale-issues-prs.yml | 5 +- LICENSE | 7 +- NOTICE | 2 + README.md | 1 + examples/streetlights-kafka.yml | 15 ++++- spec/asyncapi.md | 93 ++++++++++++++------------ 8 files changed, 90 insertions(+), 53 deletions(-) create mode 100644 NOTICE diff --git a/.github/ISSUE_TEMPLATE/release.md b/.github/ISSUE_TEMPLATE/release.md index f221a18b..5677b272 100644 --- a/.github/ISSUE_TEMPLATE/release.md +++ b/.github/ISSUE_TEMPLATE/release.md @@ -22,6 +22,20 @@ Release X.X.X is scheduled for XXXX ### Release notes: * draft PR - https://github.com/asyncapi/website/pull/PULLREQUEST +### Potential work to be included in this version + +#### Accepted + +- [ ] + +#### Pending + +- [ ] + +#### Discarded + +- [ ] + ### Progress: - [ ] Create release branches - [ ] spec @@ -59,3 +73,7 @@ Release X.X.X is scheduled for XXXX - [ ] spec-json-schemas - [ ] parser-js - [ ] Update RELEASE_PROCESS doc with any changes + +### Cleanup tasks after the release + +- [ ] diff --git a/.github/workflows/link-check-cron.yml b/.github/workflows/link-check-cron.yml index 44e1a5cb..2d1e1fc0 100644 --- a/.github/workflows/link-check-cron.yml +++ b/.github/workflows/link-check-cron.yml @@ -34,4 +34,4 @@ jobs: fields: repo,action,workflow env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CI_FAIL_NOTIFY }} - if: failure() # Only, on failure, send a message on the Slack Docs Channel (if there are broken links) + if: failure() # Only, on failure, send a message on the 94_bot-failing-ci slack channel diff --git a/.github/workflows/stale-issues-prs.yml b/.github/workflows/stale-issues-prs.yml index c1c0c61d..5dc053a4 100644 --- a/.github/workflows/stale-issues-prs.yml +++ b/.github/workflows/stale-issues-prs.yml @@ -13,7 +13,7 @@ jobs: name: Mark issue or PR as stale runs-on: ubuntu-latest steps: - - uses: actions/stale@v4.0.0 + - uses: actions/stale@v5.1.0 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: | @@ -41,4 +41,5 @@ jobs: stale-issue-label: stale stale-pr-label: stale exempt-issue-labels: keep-open - exempt-pr-labels: keep-open \ No newline at end of file + exempt-pr-labels: keep-open + close-issue-reason: not_planned diff --git a/LICENSE b/LICENSE index 23b34fdf..7a4a3ea2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,4 @@ + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -178,7 +179,7 @@ APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" + boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a @@ -186,7 +187,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright The Linux Foundation + Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -198,4 +199,4 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and - limitations under the License. + limitations under the License. \ No newline at end of file diff --git a/NOTICE b/NOTICE new file mode 100644 index 00000000..3003c18d --- /dev/null +++ b/NOTICE @@ -0,0 +1,2 @@ +AsyncAPI Initiative +Copyright The Linux Foundation \ No newline at end of file diff --git a/README.md b/README.md index 2de11dbb..c3079baa 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ ## Read the specification The latest draft specification can be found at [spec/asyncapi.md](./spec/asyncapi.md) which tracks the latest commit to the master branch in this repository. +The human-readable markdown file is the source of truth for the specification. - [Version 2.5.0](https://github.com/asyncapi/spec/blob/v2.5.0/spec/asyncapi.md) (latest) - [Version 2.4.0](https://github.com/asyncapi/spec/blob/v2.4.0/spec/asyncapi.md) diff --git a/examples/streetlights-kafka.yml b/examples/streetlights-kafka.yml index 22119954..413c36ff 100644 --- a/examples/streetlights-kafka.yml +++ b/examples/streetlights-kafka.yml @@ -15,12 +15,18 @@ info: url: https://www.apache.org/licenses/LICENSE-2.0 servers: - test: - url: test.mykafkacluster.org:8092 + scram-connections: + url: test.mykafkacluster.org:18092 protocol: kafka-secure - description: Test broker + description: Test broker secured with scramSha256 security: - saslScram: [] + mtls-connections: + url: test.mykafkacluster.org:28092 + protocol: kafka-secure + description: Test broker secured with X509 + security: + - certs: [] defaultContentType: application/json @@ -139,6 +145,9 @@ components: saslScram: type: scramSha256 description: Provide your username and password for SASL/SCRAM authentication + certs: + type: X509 + description: Download the certificate files from service provider parameters: streetlightId: diff --git a/spec/asyncapi.md b/spec/asyncapi.md index 822cba5d..0cf8749b 100644 --- a/spec/asyncapi.md +++ b/spec/asyncapi.md @@ -42,9 +42,10 @@ It means that the [application](#definitionsApplication) allows [consumers](#def - [Channel](#definitionsChannel) - [Protocol](#definitionsProtocol) - [Specification](#specification) - - [Format](#format) - - [File Structure](#file-structure) - - [Schema](#schema) + - [Format](#format) + - [File Structure](#file-structure) + - [Absolute URLs](#absolute-urls) + - [Schema](#schema) - [AsyncAPI Object](#A2SObject) - [AsyncAPI Version String](#A2SVersionString) - [Identifier](#A2SIdString) @@ -144,6 +145,10 @@ connected parts at the discretion of the author. In the latter case, [Reference By convention, the AsyncAPI Specification (A2S) file is named `asyncapi.json` or `asyncapi.yaml`. +### Absolute URLs + +Unless specified otherwise, all properties that are absolute URLs are defined by [RFC3986, section 4.3](https://datatracker.ietf.org/doc/html/rfc3986#section-4.3). + ### Schema #### AsyncAPI Object @@ -155,18 +160,18 @@ It combines resource listing and API declaration together into one document. Field Name | Type | Description ---|:---:|--- -asyncapi | [AsyncAPI Version String](#A2SVersionString) | **Required.** Specifies the AsyncAPI Specification version being used. It can be used by tooling Specifications and clients to interpret the version. The structure shall be `major`.`minor`.`patch`, where `patch` versions _must_ be compatible with the existing `major`.`minor` tooling. Typically patch versions will be introduced to address errors in the documentation, and tooling should typically be compatible with the corresponding `major`.`minor` (1.0.*). Patch versions will correspond to patches of this document. +asyncapi | [AsyncAPI Version String](#A2SVersionString) | **REQUIRED.** Specifies the AsyncAPI Specification version being used. It can be used by tooling Specifications and clients to interpret the version. The structure shall be `major`.`minor`.`patch`, where `patch` versions _must_ be compatible with the existing `major`.`minor` tooling. Typically patch versions will be introduced to address errors in the documentation, and tooling should typically be compatible with the corresponding `major`.`minor` (1.0.*). Patch versions will correspond to patches of this document. id | [Identifier](#A2SIdString) | Identifier of the [application](#definitionsApplication) the AsyncAPI document is defining. -info | [Info Object](#infoObject) | **Required.** Provides metadata about the API. The metadata can be used by the clients if needed. +info | [Info Object](#infoObject) | **REQUIRED.** Provides metadata about the API. The metadata can be used by the clients if needed. servers | [Servers Object](#serversObject) | Provides connection details of servers. defaultContentType | [Default Content Type](#defaultContentTypeString) | Default content type to use when encoding/decoding a message's payload. -channels | [Channels Object](#channelsObject) | **Required** The available channels and messages for the API. +channels | [Channels Object](#channelsObject) | **REQUIRED** The available channels and messages for the API. components | [Components Object](#componentsObject) | An element to hold various schemas for the specification. tags | [Tags Object](#tagsObject) | A list of tags used by the specification with additional metadata. Each tag name in the list MUST be unique. externalDocs | [External Documentation Object](#externalDocumentationObject) | Additional external documentation. -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). #### AsyncAPI Version String @@ -215,14 +220,14 @@ The metadata can be used by the clients if needed. Field Name | Type | Description ---|:---:|--- -title | `string` | **Required.** The title of the application. -version | `string` | **Required** Provides the version of the application API (not to be confused with the specification version). +title | `string` | **REQUIRED.** The title of the application. +version | `string` | **REQUIRED** Provides the version of the application API (not to be confused with the specification version). description | `string` | A short description of the application. [CommonMark syntax](https://spec.commonmark.org/) can be used for rich text representation. -termsOfService | `string` | A URL to the Terms of Service for the API. MUST be in the format of a URL. +termsOfService | `string` | A URL to the Terms of Service for the API. This MUST be in the form of an absolute URL. contact | [Contact Object](#contactObject) | The contact information for the exposed API. license | [License Object](#licenseObject) | The license information for the exposed API. -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). ##### Info Object Example: @@ -267,10 +272,10 @@ Contact information for the exposed API. Field Name | Type | Description ---|:---:|--- name | `string` | The identifying name of the contact person/organization. -url | `string` | The URL pointing to the contact information. MUST be in the format of a URL. +url | `string` | The URL pointing to the contact information. This MUST be in the form of an absolute URL. email | `string` | The email address of the contact person/organization. MUST be in the format of an email address. -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). ##### Contact Object Example: @@ -296,10 +301,10 @@ License information for the exposed API. Field Name | Type | Description ---|:---:|--- -name | `string` | **Required.** The license name used for the API. -url | `string` | A URL to the license used for the API. MUST be in the format of a URL. +name | `string` | **REQUIRED.** The license name used for the API. +url | `string` | A URL to the license used for the API. This MUST be in the form of an absolute URL. -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). ##### License Object Example: @@ -569,7 +574,7 @@ Describes the operations available on a single channel. Field Name | Type | Description ---|:---:|--- -$ref | `string` | Allows for an external definition of this channel item. The referenced structure MUST be in the format of a [Channel Item Object](#channelItemObject). If there are conflicts between the referenced definition and this Channel Item's definition, the behavior is *undefined*.

**Deprecated:** Usage of the `$ref` property has been deprecated. +$ref | `string` | Allows for a referenced definition of this channel item. The referenced structure MUST be in the form of a [Channel Item Object](#channelItemObject). In case a Channel Item Object field appears both in the defined object and the referenced object, the behavior is *undefined*. Resolution is done as defined by the [JSON Reference](https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03).

**Deprecated:** Usage of the `$ref` property has been deprecated. description | `string` | An optional description of this channel item. [CommonMark syntax](https://spec.commonmark.org/) can be used for rich text representation. servers | [`string`] | The servers on which this channel is available, specified as an optional unordered list of names (string keys) of [Server Objects](#serverObject) defined in the [Servers Object](#serversObject) (a map). If `servers` is absent or empty then this channel must be available on all servers defined in the [Servers Object](#serversObject). subscribe | [Operation Object](#operationObject) | A definition of the SUBSCRIBE operation, which defines the messages produced by the application and sent to the channel. @@ -577,7 +582,7 @@ Field Name | Type | Description parameters | [Parameters Object](#parametersObject) | A map of the parameters included in the channel name. It SHOULD be present only when using channels with expressions (as defined by [RFC 6570 section 2.2](https://tools.ietf.org/html/rfc6570#section-2.2)). bindings | [Channel Bindings Object](#channelBindingsObject) \| [Reference Object](#referenceObject) | A map where the keys describe the name of the protocol and the values describe protocol-specific definitions for the channel. -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). ##### Channel Item Object Example @@ -715,7 +720,7 @@ Field Name | Type | Description traits | [[Operation Trait Object](#operationTraitObject) | [Reference Object](#referenceObject) ] | A list of traits to apply to the operation object. Traits MUST be merged into the operation object using the [JSON Merge Patch](https://tools.ietf.org/html/rfc7386) algorithm in the same order they are defined here. message | [Message Object](#messageObject) | [Reference Object](#referenceObject) | Map["oneOf", [[Message Object](#messageObject) | [Reference Object](#referenceObject)]] | A definition of the message that will be published or received by this operation. Map containing a single `oneOf` key is allowed here to specify multiple messages. However, **a message MUST be valid only against one of the message objects.** -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). ##### Operation Object Example @@ -824,7 +829,7 @@ Field Name | Type | Description externalDocs | [External Documentation Object](#externalDocumentationObject) | Additional external documentation for this operation. bindings | [Operation Bindings Object](#operationBindingsObject) \| [Reference Object](#referenceObject) | A map where the keys describe the name of the protocol and the values describe protocol-specific definitions for the operation. -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). ##### Operation Trait Object Example @@ -909,7 +914,7 @@ Field Name | Type | Description schema | [Schema Object](#schemaObject) \| [Reference Object](#referenceObject) | Definition of the parameter. location | `string` | A [runtime expression](#runtimeExpression) that specifies the location of the parameter value. Even when a definition for the target field exists, it MUST NOT be used to validate this parameter but, instead, the `schema` property MUST be used. -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). ##### Parameter Object Example @@ -976,7 +981,7 @@ Field Name | Type | Description `mercure` | [Mercure Server Binding](https://github.com/asyncapi/bindings/blob/master/mercure#server) | Protocol-specific information for a Mercure server. `ibmmq` | [IBM MQ Server Binding](https://github.com/asyncapi/bindings/blob/master/ibmmq#server-binding-object) | Protocol-specific information for an IBM MQ server. -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). @@ -1006,7 +1011,7 @@ Field Name | Type | Description `mercure` | [Mercure Channel Binding](https://github.com/asyncapi/bindings/blob/master/mercure#channel) | Protocol-specific information for a Mercure channel. `ibmmq` | [IBM MQ Channel Binding](https://github.com/asyncapi/bindings/tree/master/ibmmq#channel-binding-object) | Protocol-specific information for an IBM MQ channel. -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). @@ -1035,7 +1040,7 @@ Field Name | Type | Description `redis` | [Redis Operation Binding](https://github.com/asyncapi/bindings/blob/master/redis#operation) | Protocol-specific information for a Redis operation. `mercure` | [Mercure Operation Binding](https://github.com/asyncapi/bindings/blob/master/mercure#operation) | Protocol-specific information for a Mercure operation. -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). @@ -1066,7 +1071,7 @@ Field Name | Type | Description `mercure` | [Mercure Message Binding](https://github.com/asyncapi/bindings/blob/master/mercure#message) | Protocol-specific information for a Mercure message. `ibmmq` | [IBM MQ Message Binding](https://github.com/asyncapi/bindings/tree/master/ibmmq#message-binding-object) | Protocol-specific information for an IBM MQ message. -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). @@ -1098,7 +1103,7 @@ Field Name | Type | Description examples | [[Message Example Object](#messageExampleObject)] | List of examples. traits | [[Message Trait Object](#messageTraitObject) | [Reference Object](#referenceObject)] | A list of traits to apply to the message object. Traits MUST be merged into the message object using the [JSON Merge Patch](https://tools.ietf.org/html/rfc7386) algorithm in the same order they are defined here. The resulting object MUST be a valid [Message Object](#messageObject). -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). ##### Schema formats table @@ -1296,7 +1301,7 @@ Field Name | Type | Description bindings | [Message Bindings Object](#messageBindingsObject) \| [Reference Object](#referenceObject) | A map where the keys describe the name of the protocol and the values describe protocol-specific definitions for the message. examples | [[Message Example Object](#messageExampleObject)] | List of examples. -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). ##### Message Trait Object Example @@ -1325,7 +1330,7 @@ Field Name | Type | Description name | `string` | A machine-friendly name. summary | `string` | A short summary of what the example is about. -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). ##### Message Example Object Example @@ -1372,11 +1377,11 @@ Allows adding meta data to a single tag. ##### Fixed Fields Field Name | Type | Description ---|:---:|--- -name | `string` | **Required.** The name of the tag. +name | `string` | **REQUIRED.** The name of the tag. description | `string` | A short description for the tag. [CommonMark syntax](https://spec.commonmark.org/) can be used for rich text representation. externalDocs | [External Documentation Object](#externalDocumentationObject) | Additional external documentation for this tag. -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). ##### Tag Object Example @@ -1407,9 +1412,9 @@ Allows referencing an external resource for extended documentation. Field Name | Type | Description ---|:---:|--- description | `string` | A short description of the target documentation. [CommonMark syntax](https://spec.commonmark.org/) can be used for rich text representation. -url | `string` | **Required.** The URL for the target documentation. Value MUST be in the format of a URL. +url | `string` | **REQUIRED.** The URL for the target documentation. This MUST be in the form of an absolute URL. -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). ##### External Documentation Object Example @@ -1436,7 +1441,7 @@ For this specification, reference resolution is done as defined by the JSON Refe ##### Fixed Fields Field Name | Type | Description ---|:---:|--- -$ref | `string` | **Required.** The reference string. +$ref | `string` | **REQUIRED.** The reference string. This object cannot be extended with additional properties and any properties added SHALL be ignored. @@ -1476,7 +1481,7 @@ Field Name | Type | Description operationBindings | Map[`string`, [Operation Bindings Object](#operationBindingsObject) \| [Reference Object](#referenceObject)] | An object to hold reusable [Operation Bindings Objects](#operationBindingsObject). messageBindings | Map[`string`, [Message Bindings Object](#messageBindingsObject) \| [Reference Object](#referenceObject)] | An object to hold reusable [Message Bindings Objects](#messageBindingsObject). -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). All the fixed fields declared above are objects that MUST use keys that match the regular expression: `^[a-zA-Z0-9\.\-_]+$`. @@ -1769,7 +1774,7 @@ Field Name | Type | Description externalDocs | [External Documentation Object](#externalDocumentationObject) | Additional external documentation for this schema. deprecated | `boolean` | Specifies that a schema is deprecated and SHOULD be transitioned out of usage. Default value is `false`. -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). ###### Composition and Inheritance (Polymorphism) @@ -2198,7 +2203,7 @@ Field Name | Type | Applies To | Description scheme | `string` | `http` | **REQUIRED**. The name of the HTTP Authorization scheme to be used in the [Authorization header as defined in RFC7235](https://tools.ietf.org/html/rfc7235#section-5.1). bearerFormat | `string` | `http` (`"bearer"`) | A hint to the client to identify how the bearer token is formatted. Bearer tokens are usually generated by an authorization server, so this information is primarily for documentation purposes. flows | [OAuth Flows Object](#oauthFlowsObject) | `oauth2` | **REQUIRED**. An object containing configuration information for the flow types supported. -openIdConnectUrl | `string` | `openIdConnect` | **REQUIRED**. OpenId Connect URL to discover OAuth2 configuration values. This MUST be in the form of a URL. +openIdConnectUrl | `string` | `openIdConnect` | **REQUIRED**. OpenId Connect URL to discover OAuth2 configuration values. This MUST be in the form of an absolute URL. This object MAY be extended with [Specification Extensions](#specificationExtensions). @@ -2346,8 +2351,8 @@ Allows configuration of the supported OAuth Flows. ##### Fixed Fields Field Name | Type | Description ---|:---:|--- -implicit| [OAuth Flow Object](#oauthFlowObject) | Configuration for the OAuth Implicit flow -password| [OAuth Flow Object](#oauthFlowObject) | Configuration for the OAuth Resource Owner Protected Credentials flow +implicit| [OAuth Flow Object](#oauthFlowObject) | Configuration for the OAuth Implicit flow. +password| [OAuth Flow Object](#oauthFlowObject) | Configuration for the OAuth Resource Owner Protected Credentials flow. clientCredentials| [OAuth Flow Object](#oauthFlowObject) | Configuration for the OAuth Client Credentials flow. authorizationCode| [OAuth Flow Object](#oauthFlowObject) | Configuration for the OAuth Authorization Code flow. @@ -2360,9 +2365,9 @@ Configuration details for a supported OAuth Flow ##### Fixed Fields Field Name | Type | Applies To | Description ---|:---:|---|--- -authorizationUrl | `string` | `oauth2` (`"implicit"`, `"authorizationCode"`) | **REQUIRED**. The authorization URL to be used for this flow. This MUST be in the form of a URL. -tokenUrl | `string` | `oauth2` (`"password"`, `"clientCredentials"`, `"authorizationCode"`) | **REQUIRED**. The token URL to be used for this flow. This MUST be in the form of a URL. -refreshUrl | `string` | `oauth2` | The URL to be used for obtaining refresh tokens. This MUST be in the form of a URL. +authorizationUrl | `string` | `oauth2` (`"implicit"`, `"authorizationCode"`) | **REQUIRED**. The authorization URL to be used for this flow. This MUST be in the form of an absolute URL. +tokenUrl | `string` | `oauth2` (`"password"`, `"clientCredentials"`, `"authorizationCode"`) | **REQUIRED**. The token URL to be used for this flow. This MUST be in the form of an absolute URL. +refreshUrl | `string` | `oauth2` | The URL to be used for obtaining refresh tokens. This MUST be in the form of an absolute URL. scopes | Map[`string`, `string`] | `oauth2` | **REQUIRED**. The available scopes for the OAuth2 security scheme. A map between the scope name and a short description for it. This object MAY be extended with [Specification Extensions](#specificationExtensions). @@ -2477,7 +2482,7 @@ Field Name | Type | Description description | `string` | An optional description of the identifier. [CommonMark syntax](https://spec.commonmark.org/) can be used for rich text representation. location | `string` | **REQUIRED.** A [runtime expression](#runtimeExpression) that specifies the location of the correlation ID. -This object can be extended with [Specification Extensions](#specificationExtensions). +This object MAY be extended with [Specification Extensions](#specificationExtensions). ##### Examples @@ -2553,6 +2558,6 @@ string | `string` | | | byte | `string` | `byte` | base64 encoded characters binary | `string` | `binary` | any sequence of octets boolean | `boolean` | | | -date | `string` | `date` | As defined by `full-date` - [RFC3339](https://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14) -dateTime | `string` | `date-time` | As defined by `date-time` - [RFC3339](https://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14) +date | `string` | `date` | As defined by `full-date` - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339.html#section-5.6) +dateTime | `string` | `date-time` | As defined by `date-time` - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339.html#section-5.6) password | `string` | `password` | Used to hint UIs the input needs to be obscured. From 5deef1e9148947689d53db3a1d013d49cd9df7d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Gorej?= Date: Thu, 15 Sep 2022 11:10:42 +0200 Subject: [PATCH 4/8] feat: allow re-usability of Server Variable Objects (#776) --- spec/asyncapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/asyncapi.md b/spec/asyncapi.md index 0cf8749b..fb6db37b 100644 --- a/spec/asyncapi.md +++ b/spec/asyncapi.md @@ -364,7 +364,7 @@ Field Name | Type | Description protocol | `string` | **REQUIRED**. The protocol this URL supports for connection. Supported protocol include, but are not limited to: `amqp`, `amqps`, `http`, `https`, `ibmmq`, `jms`, `kafka`, `kafka-secure`, `anypointmq`, `mqtt`, `secure-mqtt`, `solace`, `stomp`, `stomps`, `ws`, `wss`, `mercure`. protocolVersion | `string` | The version of the protocol used for connection. For instance: AMQP `0.9.1`, HTTP `2.0`, Kafka `1.0.0`, etc. description | `string` | An optional string describing the host designated by the URL. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation. -variables | Map[`string`, [Server Variable Object](#serverVariableObject)] | A map between a variable name and its value. The value is used for substitution in the server's URL template. +variables | Map[`string`, [Server Variable Object](#serverVariableObject) \| [Reference Object](#referenceObject)]] | A map between a variable name and its value. The value is used for substitution in the server's URL template. security | [[Security Requirement Object](#securityRequirementObject)] | A declaration of which security mechanisms can be used with this server. The list of values includes alternative security requirement objects that can be used. Only one of the security requirement objects need to be satisfied to authorize a connection or operation. bindings | [Server Bindings Object](#serverBindingsObject) \| [Reference Object](#referenceObject) | A map where the keys describe the name of the protocol and the values describe protocol-specific definitions for the server. From 0a83b9b91b765f9c6f61d7098aba68001a07cd46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Gorej?= Date: Thu, 22 Sep 2022 10:05:59 +0200 Subject: [PATCH 5/8] ci: fix release workflow to support release branches (#839) --- .github/workflows/if-nodejs-release.yml | 9 +++------ .github/workflows/release.yml | 3 ++- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/if-nodejs-release.yml b/.github/workflows/if-nodejs-release.yml index bc5b5376..4a34feb0 100644 --- a/.github/workflows/if-nodejs-release.yml +++ b/.github/workflows/if-nodejs-release.yml @@ -9,12 +9,9 @@ on: branches: - master # below lines are not enough to have release supported for these branches - # make sure configuration of `semantic-release` package mentiones these branches - - next - - next-major - - beta - - alpha - - '**-release' # custom + # make sure configuration of `semantic-release` package mentions these branches + - next-spec + - next-major-spec jobs: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d731487b..8252eadd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,7 +4,8 @@ on: push: branches: - master - - '**-release' + - next-spec + - next-major-spec jobs: release: From b0c2f9c086d940e8016ec1fa60107fe74cc070db Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Thu, 22 Sep 2022 10:55:34 +0200 Subject: [PATCH 6/8] feat: add tags field to Server Object (#809) --- examples/social-media/backend/asyncapi.yaml | 7 ++++ .../comments-service/asyncapi.yaml | 7 ++++ .../notification-service/asyncapi.yaml | 7 ++++ .../social-media/public-api/asyncapi.yaml | 7 ++++ examples/streetlights-kafka.yml | 14 +++++++ examples/streetlights-mqtt.yml | 7 ++++ spec/asyncapi.md | 42 +++++++++++++++---- 7 files changed, 84 insertions(+), 7 deletions(-) diff --git a/examples/social-media/backend/asyncapi.yaml b/examples/social-media/backend/asyncapi.yaml index cefc2f98..5f7cb94e 100644 --- a/examples/social-media/backend/asyncapi.yaml +++ b/examples/social-media/backend/asyncapi.yaml @@ -13,6 +13,13 @@ servers: bindings: mqtt: clientId: websocketServer + tags: + - name: "env:production" + description: "This environment is meant for production use case" + - name: "kind:remote" + description: "This server is a remote server. Not exposed by the application" + - name: "visibility:public" + description: "This resource is public and available to everyone" channels: comment/liked: diff --git a/examples/social-media/comments-service/asyncapi.yaml b/examples/social-media/comments-service/asyncapi.yaml index 0c0bddfd..ce8f93a9 100644 --- a/examples/social-media/comments-service/asyncapi.yaml +++ b/examples/social-media/comments-service/asyncapi.yaml @@ -12,6 +12,13 @@ servers: bindings: mqtt: clientId: comment-service + tags: + - name: "env:production" + description: "This environment is meant for production use case" + - name: "kind:remote" + description: "This server is a remote server. Not exposed by the application" + - name: "visibility:public" + description: "This resource is public and available to everyone" channels: comment/liked: diff --git a/examples/social-media/notification-service/asyncapi.yaml b/examples/social-media/notification-service/asyncapi.yaml index 9952c962..be78362c 100644 --- a/examples/social-media/notification-service/asyncapi.yaml +++ b/examples/social-media/notification-service/asyncapi.yaml @@ -11,6 +11,13 @@ servers: bindings: mqtt: clientId: notification-service + tags: + - name: "env:production" + description: "This environment is meant for production use case" + - name: "kind:remote" + description: "This server is a remote server. Not exposed by the application" + - name: "visibility:public" + description: "This resource is public and available to everyone" channels: comment/liked: diff --git a/examples/social-media/public-api/asyncapi.yaml b/examples/social-media/public-api/asyncapi.yaml index 9e9ea1ef..0a7cdde7 100644 --- a/examples/social-media/public-api/asyncapi.yaml +++ b/examples/social-media/public-api/asyncapi.yaml @@ -12,6 +12,13 @@ servers: bindings: mqtt: clientId: public-api + tags: + - name: "env:production" + description: "This environment is meant for production use case" + - name: "kind:remote" + description: "This server is a remote server. Not exposed by the application" + - name: "visibility:public" + description: "This resource is public and available to everyone" channels: comment/liked: diff --git a/examples/streetlights-kafka.yml b/examples/streetlights-kafka.yml index 413c36ff..91611115 100644 --- a/examples/streetlights-kafka.yml +++ b/examples/streetlights-kafka.yml @@ -21,12 +21,26 @@ servers: description: Test broker secured with scramSha256 security: - saslScram: [] + tags: + - name: "env:test-scram" + description: "This environment is meant for running internal tests through scramSha256" + - name: "kind:remote" + description: "This server is a remote server. Not exposed by the application" + - name: "visibility:private" + description: "This resource is private and only available to certain users" mtls-connections: url: test.mykafkacluster.org:28092 protocol: kafka-secure description: Test broker secured with X509 security: - certs: [] + tags: + - name: "env:test-mtls" + description: "This environment is meant for running internal tests through mtls" + - name: "kind:remote" + description: "This server is a remote server. Not exposed by the application" + - name: "visibility:private" + description: "This resource is private and only available to certain users" defaultContentType: application/json diff --git a/examples/streetlights-mqtt.yml b/examples/streetlights-mqtt.yml index 450ec442..b3721d87 100644 --- a/examples/streetlights-mqtt.yml +++ b/examples/streetlights-mqtt.yml @@ -33,6 +33,13 @@ servers: - streetlights:off - streetlights:dim - openIdConnectWellKnown: [] + tags: + - name: "env:production" + description: "This environment is meant for production use case" + - name: "kind:remote" + description: "This server is a remote server. Not exposed by the application" + - name: "visibility:public" + description: "This resource is public and available to everyone" defaultContentType: application/json diff --git a/spec/asyncapi.md b/spec/asyncapi.md index fb6db37b..cb470825 100644 --- a/spec/asyncapi.md +++ b/spec/asyncapi.md @@ -366,6 +366,7 @@ Field Name | Type | Description description | `string` | An optional string describing the host designated by the URL. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation. variables | Map[`string`, [Server Variable Object](#serverVariableObject) \| [Reference Object](#referenceObject)]] | A map between a variable name and its value. The value is used for substitution in the server's URL template. security | [[Security Requirement Object](#securityRequirementObject)] | A declaration of which security mechanisms can be used with this server. The list of values includes alternative security requirement objects that can be used. Only one of the security requirement objects need to be satisfied to authorize a connection or operation. +tags | [Tags Object](#tagsObject) | A list of tags for logical grouping and categorization of servers. bindings | [Server Bindings Object](#serverBindingsObject) \| [Reference Object](#referenceObject) | A map where the keys describe the name of the protocol and the values describe protocol-specific definitions for the server. This object MAY be extended with [Specification Extensions](#specificationExtensions). @@ -399,19 +400,37 @@ The following shows how multiple servers can be described, for example, at the A "url": "development.gigantic-server.com", "description": "Development server", "protocol": "amqp", - "protocolVersion": "0.9.1" + "protocolVersion": "0.9.1", + "tags": [ + { + "name": "env:development", + "description": "This environment is meant for developers to run their own tests" + } + ] }, "staging": { "url": "staging.gigantic-server.com", "description": "Staging server", "protocol": "amqp", - "protocolVersion": "0.9.1" + "protocolVersion": "0.9.1", + "tags": [ + { + "name": "env:staging", + "description": "This environment is a replica of the production environment" + } + ] }, "production": { "url": "api.gigantic-server.com", "description": "Production server", "protocol": "amqp", - "protocolVersion": "0.9.1" + "protocolVersion": "0.9.1", + "tags": [ + { + "name": "env:production", + "description": "This environment is the live environment available for final users" + } + ] } } } @@ -424,16 +443,25 @@ servers: description: Development server protocol: amqp protocolVersion: 0.9.1 + tags: + - name: "env:development" + description: "This environment is meant for developers to run their own tests" staging: url: staging.gigantic-server.com description: Staging server protocol: amqp protocolVersion: 0.9.1 + tags: + - name: "env:staging" + description: "This environment is a replica of the production environment" production: url: api.gigantic-server.com description: Production server protocol: amqp protocolVersion: 0.9.1 + tags: + - name: "env:production" + description: "This environment is the live environment available for final users" ``` The following shows how variables can be used for a server configuration: @@ -714,7 +742,7 @@ Field Name | Type | Description summary | `string` | A short summary of what the operation is about. description | `string` | A verbose explanation of the operation. [CommonMark syntax](http://spec.commonmark.org/) can be used for rich text representation. security | [[Security Requirement Object](#securityRequirementObject)]| A declaration of which security mechanisms are associated with this operation. Only one of the security requirement objects MUST be satisfied to authorize an operation. In cases where Server Security also applies, it MUST also be satisfied. -tags | [Tags Object](#tagsObject) | A list of tags for API documentation control. Tags can be used for logical grouping of operations. +tags | [Tags Object](#tagsObject) | A list of tags for logical grouping and categorization of operations. externalDocs | [External Documentation Object](#externalDocumentationObject) | Additional external documentation for this operation. bindings | [Operation Bindings Object](#operationBindingsObject) \| [Reference Object](#referenceObject) | A map where the keys describe the name of the protocol and the values describe protocol-specific definitions for the operation. traits | [[Operation Trait Object](#operationTraitObject) | [Reference Object](#referenceObject) ] | A list of traits to apply to the operation object. Traits MUST be merged into the operation object using the [JSON Merge Patch](https://tools.ietf.org/html/rfc7386) algorithm in the same order they are defined here. @@ -825,7 +853,7 @@ Field Name | Type | Description summary | `string` | A short summary of what the operation is about. description | `string` | A verbose explanation of the operation. [CommonMark syntax](https://spec.commonmark.org/) can be used for rich text representation. security | [[Security Requirement Object](#securityRequirementObject)]| A declaration of which security mechanisms are associated with this operation. Only one of the security requirement objects MUST be satisfied to authorize an operation. In cases where Server Security also applies, it MUST also be satisfied. -tags | [Tags Object](#tagsObject) | A list of tags for API documentation control. Tags can be used for logical grouping of operations. +tags | [Tags Object](#tagsObject) | A list of tags for logical grouping and categorization of operations. externalDocs | [External Documentation Object](#externalDocumentationObject) | Additional external documentation for this operation. bindings | [Operation Bindings Object](#operationBindingsObject) \| [Reference Object](#referenceObject) | A map where the keys describe the name of the protocol and the values describe protocol-specific definitions for the operation. @@ -1097,7 +1125,7 @@ Field Name | Type | Description title | `string` | A human-friendly title for the message. summary | `string` | A short summary of what the message is about. description | `string` | A verbose explanation of the message. [CommonMark syntax](https://spec.commonmark.org/) can be used for rich text representation. -tags | [Tags Object](#tagsObject) | A list of tags for API documentation control. Tags can be used for logical grouping of messages. +tags | [Tags Object](#tagsObject) | A list of tags for logical grouping and categorization of messages. externalDocs | [External Documentation Object](#externalDocumentationObject) | Additional external documentation for this message. bindings | [Message Bindings Object](#messageBindingsObject) \| [Reference Object](#referenceObject) | A map where the keys describe the name of the protocol and the values describe protocol-specific definitions for the message. examples | [[Message Example Object](#messageExampleObject)] | List of examples. @@ -1296,7 +1324,7 @@ Field Name | Type | Description title | `string` | A human-friendly title for the message. summary | `string` | A short summary of what the message is about. description | `string` | A verbose explanation of the message. [CommonMark syntax](https://spec.commonmark.org/) can be used for rich text representation. -tags | [Tags Object](#tagsObject) | A list of tags for API documentation control. Tags can be used for logical grouping of messages. +tags | [Tags Object](#tagsObject) | A list of tags for logical grouping and categorization of messages. externalDocs | [External Documentation Object](#externalDocumentationObject) | Additional external documentation for this message. bindings | [Message Bindings Object](#messageBindingsObject) \| [Reference Object](#referenceObject) | A map where the keys describe the name of the protocol and the values describe protocol-specific definitions for the message. examples | [[Message Example Object](#messageExampleObject)] | List of examples. From 68d85d19e5be12fa6e13d0fc5851993934dbdcde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Urba=C5=84czyk?= Date: Sat, 24 Sep 2022 14:24:33 +0200 Subject: [PATCH 7/8] fix: add missed IBM MQ Operation Binding (#840) --- spec/asyncapi.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/asyncapi.md b/spec/asyncapi.md index cb470825..09cb12b2 100644 --- a/spec/asyncapi.md +++ b/spec/asyncapi.md @@ -1067,6 +1067,7 @@ Field Name | Type | Description `stomp` | [STOMP Operation Binding](https://github.com/asyncapi/bindings/blob/master/stomp/README.md#operation) | Protocol-specific information for a STOMP operation. `redis` | [Redis Operation Binding](https://github.com/asyncapi/bindings/blob/master/redis#operation) | Protocol-specific information for a Redis operation. `mercure` | [Mercure Operation Binding](https://github.com/asyncapi/bindings/blob/master/mercure#operation) | Protocol-specific information for a Mercure operation. +`ibmmq` | [IBM MQ Operation Binding](https://github.com/asyncapi/bindings/blob/master/ibmmq#operation-binding-object) | Protocol-specific information for an IBM MQ operation. This object MAY be extended with [Specification Extensions](#specificationExtensions). From babc3bedb5d85375a305c7268e96257113c1933e Mon Sep 17 00:00:00 2001 From: Jeremy Whitlock Date: Tue, 27 Sep 2022 01:17:46 -0600 Subject: [PATCH 8/8] feat: add googlepubsub bindings (#836) --- spec/asyncapi.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spec/asyncapi.md b/spec/asyncapi.md index 09cb12b2..a2799ffb 100644 --- a/spec/asyncapi.md +++ b/spec/asyncapi.md @@ -361,7 +361,7 @@ An object representing a message broker, a server or any other kind of computer Field Name | Type | Description ---|:---:|--- url | `string` | **REQUIRED**. A URL to the target host. This URL supports Server Variables and MAY be relative, to indicate that the host location is relative to the location where the AsyncAPI document is being served. Variable substitutions will be made when a variable is named in `{`braces`}`. -protocol | `string` | **REQUIRED**. The protocol this URL supports for connection. Supported protocol include, but are not limited to: `amqp`, `amqps`, `http`, `https`, `ibmmq`, `jms`, `kafka`, `kafka-secure`, `anypointmq`, `mqtt`, `secure-mqtt`, `solace`, `stomp`, `stomps`, `ws`, `wss`, `mercure`. +protocol | `string` | **REQUIRED**. The protocol this URL supports for connection. Supported protocol include, but are not limited to: `amqp`, `amqps`, `http`, `https`, `ibmmq`, `jms`, `kafka`, `kafka-secure`, `anypointmq`, `mqtt`, `secure-mqtt`, `solace`, `stomp`, `stomps`, `ws`, `wss`, `mercure`, `googlepubsub`. protocolVersion | `string` | The version of the protocol used for connection. For instance: AMQP `0.9.1`, HTTP `2.0`, Kafka `1.0.0`, etc. description | `string` | An optional string describing the host designated by the URL. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation. variables | Map[`string`, [Server Variable Object](#serverVariableObject) \| [Reference Object](#referenceObject)]] | A map between a variable name and its value. The value is used for substitution in the server's URL template. @@ -1008,6 +1008,7 @@ Field Name | Type | Description `redis` | [Redis Server Binding](https://github.com/asyncapi/bindings/blob/master/redis#server) | Protocol-specific information for a Redis server. `mercure` | [Mercure Server Binding](https://github.com/asyncapi/bindings/blob/master/mercure#server) | Protocol-specific information for a Mercure server. `ibmmq` | [IBM MQ Server Binding](https://github.com/asyncapi/bindings/blob/master/ibmmq#server-binding-object) | Protocol-specific information for an IBM MQ server. +`googlepubsub` | [Google Cloud Pub/Sub Server Binding](https://github.com/asyncapi/bindings/blob/master/googlepubsub#server) | Protocol-specific information for a Google Cloud Pub/Sub server. This object MAY be extended with [Specification Extensions](#specificationExtensions). @@ -1038,6 +1039,7 @@ Field Name | Type | Description `redis` | [Redis Channel Binding](https://github.com/asyncapi/bindings/blob/master/redis#channel) | Protocol-specific information for a Redis channel. `mercure` | [Mercure Channel Binding](https://github.com/asyncapi/bindings/blob/master/mercure#channel) | Protocol-specific information for a Mercure channel. `ibmmq` | [IBM MQ Channel Binding](https://github.com/asyncapi/bindings/tree/master/ibmmq#channel-binding-object) | Protocol-specific information for an IBM MQ channel. +`googlepubsub` | [Google Cloud Pub/Sub Channel Binding](https://github.com/asyncapi/bindings/tree/master/googlepubsub#channel) | Protocol-specific information for a Google Cloud Pub/Sub channel. This object MAY be extended with [Specification Extensions](#specificationExtensions). @@ -1067,6 +1069,7 @@ Field Name | Type | Description `stomp` | [STOMP Operation Binding](https://github.com/asyncapi/bindings/blob/master/stomp/README.md#operation) | Protocol-specific information for a STOMP operation. `redis` | [Redis Operation Binding](https://github.com/asyncapi/bindings/blob/master/redis#operation) | Protocol-specific information for a Redis operation. `mercure` | [Mercure Operation Binding](https://github.com/asyncapi/bindings/blob/master/mercure#operation) | Protocol-specific information for a Mercure operation. +`googlepubsub` | [Google Cloud Pub/Sub Operation Binding](https://github.com/asyncapi/bindings/blob/master/googlepubsub#operation) | Protocol-specific information for a Google Cloud Pub/Sub operation. `ibmmq` | [IBM MQ Operation Binding](https://github.com/asyncapi/bindings/blob/master/ibmmq#operation-binding-object) | Protocol-specific information for an IBM MQ operation. This object MAY be extended with [Specification Extensions](#specificationExtensions). @@ -1099,6 +1102,7 @@ Field Name | Type | Description `redis` | [Redis Message Binding](https://github.com/asyncapi/bindings/blob/master/redis#message) | Protocol-specific information for a Redis message. `mercure` | [Mercure Message Binding](https://github.com/asyncapi/bindings/blob/master/mercure#message) | Protocol-specific information for a Mercure message. `ibmmq` | [IBM MQ Message Binding](https://github.com/asyncapi/bindings/tree/master/ibmmq#message-binding-object) | Protocol-specific information for an IBM MQ message. +`googlepubsub` | [Google Cloud Pub/Sub Message Binding](https://github.com/asyncapi/bindings/tree/master/googlepubsub#message) | Protocol-specific information for a Google Cloud Pub/Sub message. This object MAY be extended with [Specification Extensions](#specificationExtensions).