From 9549230a2b716943ca908b7fd3916cf77d019be3 Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Fri, 28 Oct 2022 17:21:28 +0200 Subject: [PATCH 01/37] docs: set proper indentation for the TOC (#853) --- spec/asyncapi.md | 78 ++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/spec/asyncapi.md b/spec/asyncapi.md index a2799ffbb..f78e94b1c 100644 --- a/spec/asyncapi.md +++ b/spec/asyncapi.md @@ -42,45 +42,45 @@ It means that the [application](#definitionsApplication) allows [consumers](#def - [Channel](#definitionsChannel) - [Protocol](#definitionsProtocol) - [Specification](#specification) - - [Format](#format) - - [File Structure](#file-structure) - - [Absolute URLs](#absolute-urls) - - [Schema](#schema) - - [AsyncAPI Object](#A2SObject) - - [AsyncAPI Version String](#A2SVersionString) - - [Identifier](#A2SIdString) - - [Info Object](#infoObject) - - [Contact Object](#contactObject) - - [License Object](#licenseObject) - - [Servers Object](#serversObject) - - [Server Object](#serverObject) - - [Server Variable Object](#serverVariableObject) - - [Default Content Type](#defaultContentTypeString) - - [Channels Object](#channelsObject) - - [Channel Item Object](#channelItemObject) - - [Operation Object](#operationObject) - - [Operation Trait Object](#operationTraitObject) - - [Message Object](#messageObject) - - [Message Trait Object](#messageTraitObject) - - [Message Example Object](#messageExampleObject) - - [Tags Object](#tagsObject) - - [Tag Object](#tag-object) - - [External Documentation Object](#externalDocumentationObject) - - [Components Object](#componentsObject) - - [Reference Object](#referenceObject) - - [Schema Object](#schemaObject) - - [Security Scheme Object](#securitySchemeObject) - - [Security Requirement Object](#security-requirement-object) - - [OAuth Flows Object](#oauth-flows-object) - - [OAuth Flow Object](#oauth-flow-object) - - [Server Bindings Object](#serverBindingsObject) - - [Parameters Object](#parametersObject) - - [Parameter Object](#parameterObject) - - [Channel Bindings Object](#channelBindingsObject) - - [Operation Bindings Object](#operationBindingsObject) - - [Message Bindings Object](#messageBindingsObject) - - [Correlation ID Object](#correlationIdObject) - - [Specification Extensions](#specificationExtensions) + - [Format](#format) + - [File Structure](#file-structure) + - [Absolute URLs](#absolute-urls) + - [Schema](#schema) + - [AsyncAPI Object](#A2SObject) + - [AsyncAPI Version String](#A2SVersionString) + - [Identifier](#A2SIdString) + - [Info Object](#infoObject) + - [Contact Object](#contactObject) + - [License Object](#licenseObject) + - [Servers Object](#serversObject) + - [Server Object](#serverObject) + - [Server Variable Object](#serverVariableObject) + - [Default Content Type](#defaultContentTypeString) + - [Channels Object](#channelsObject) + - [Channel Item Object](#channelItemObject) + - [Operation Object](#operationObject) + - [Operation Trait Object](#operationTraitObject) + - [Message Object](#messageObject) + - [Message Trait Object](#messageTraitObject) + - [Message Example Object](#messageExampleObject) + - [Tags Object](#tagsObject) + - [Tag Object](#tag-object) + - [External Documentation Object](#externalDocumentationObject) + - [Components Object](#componentsObject) + - [Reference Object](#referenceObject) + - [Schema Object](#schemaObject) + - [Security Scheme Object](#securitySchemeObject) + - [Security Requirement Object](#security-requirement-object) + - [OAuth Flows Object](#oauth-flows-object) + - [OAuth Flow Object](#oauth-flow-object) + - [Server Bindings Object](#serverBindingsObject) + - [Parameters Object](#parametersObject) + - [Parameter Object](#parameterObject) + - [Channel Bindings Object](#channelBindingsObject) + - [Operation Bindings Object](#operationBindingsObject) + - [Message Bindings Object](#messageBindingsObject) + - [Correlation ID Object](#correlationIdObject) + - [Specification Extensions](#specificationExtensions) From 226447a01966bca188bec83da2c001f96fed39cf Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Wed, 9 Nov 2022 19:29:03 +0100 Subject: [PATCH 02/37] ci: update generic workflows (#871) --- ...d-ready-to-merge-or-do-not-merge-label.yml | 17 +- ...ns-remove-ready-to-merge-label-on-edit.yml | 5 +- .../workflows/issues-prs-notifications.yml | 104 ++-- .github/workflows/link-check-cron.yml | 38 +- .github/workflows/link-check-pr.yml | 27 +- .github/workflows/lint-pr-title.yml | 36 +- .../workflows/notify-tsc-members-mention.yml | 575 +++++++++--------- 7 files changed, 397 insertions(+), 405 deletions(-) diff --git a/.github/workflows/automerge-for-humans-add-ready-to-merge-or-do-not-merge-label.yml b/.github/workflows/automerge-for-humans-add-ready-to-merge-or-do-not-merge-label.yml index e00a45fa3..79c8079ec 100644 --- a/.github/workflows/automerge-for-humans-add-ready-to-merge-or-do-not-merge-label.yml +++ b/.github/workflows/automerge-for-humans-add-ready-to-merge-or-do-not-merge-label.yml @@ -7,14 +7,14 @@ name: Label PRs # if proper comment added -on: - issue_comment: - types: - - created +on: + issue_comment: + types: + - created jobs: add-ready-to-merge-label: - if: > + if: > github.event.issue.pull_request && github.event.issue.state != 'closed' && github.actor != 'asyncapi-bot' && @@ -25,7 +25,6 @@ jobs: runs-on: ubuntu-latest steps: - - name: Add ready-to-merge label uses: actions/github-script@v5 with: @@ -64,7 +63,7 @@ jobs: Thanks 😄` }) } - + add-do-not-merge-label: if: > github.event.issue.pull_request && @@ -86,7 +85,7 @@ jobs: owner: context.repo.owner, repo: context.repo.repo, labels: ['do-not-merge'] - }) + }) add-autoupdate-label: if: > github.event.issue.pull_request && @@ -108,4 +107,4 @@ jobs: owner: context.repo.owner, repo: context.repo.repo, labels: ['autoupdate'] - }) + }) diff --git a/.github/workflows/automerge-for-humans-remove-ready-to-merge-label-on-edit.yml b/.github/workflows/automerge-for-humans-remove-ready-to-merge-label-on-edit.yml index f38296c8d..b8fc9904d 100644 --- a/.github/workflows/automerge-for-humans-remove-ready-to-merge-label-on-edit.yml +++ b/.github/workflows/automerge-for-humans-remove-ready-to-merge-label-on-edit.yml @@ -22,14 +22,11 @@ jobs: script: | const labelToRemove = 'ready-to-merge'; const labels = context.payload.pull_request.labels; - const isLabelPresent = labels.some(label => label.name === labelToRemove) - if(!isLabelPresent) return; - github.rest.issues.removeLabel({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, name: labelToRemove - }) + }) diff --git a/.github/workflows/issues-prs-notifications.yml b/.github/workflows/issues-prs-notifications.yml index 576b2bac8..ca665404b 100644 --- a/.github/workflows/issues-prs-notifications.yml +++ b/.github/workflows/issues-prs-notifications.yml @@ -5,7 +5,6 @@ name: Notify slack on: - issues: types: [opened, reopened] @@ -16,57 +15,56 @@ on: types: [created] jobs: + issue: + if: github.event_name == 'issues' && github.actor != 'asyncapi-bot' && github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' + name: Notify slack on every new issue + runs-on: ubuntu-latest + steps: + - name: Convert markdown to slack markdown for issue + uses: LoveToKnow/slackify-markdown-action@v1.0.0 + id: issuemarkdown + with: + text: "[${{github.event.issue.title}}](${{github.event.issue.html_url}}) \n ${{github.event.issue.body}}" + - name: Send info about issue + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_WEBHOOK: ${{secrets.SLACK_GITHUB_NEWISSUEPR}} + SLACK_TITLE: 🐛 New Issue in ${{github.repository}} 🐛 + SLACK_MESSAGE: ${{steps.issuemarkdown.outputs.text}} + MSG_MINIMAL: true - issue: - if: github.event_name == 'issues' && github.actor != 'asyncapi-bot' && github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' - name: Notify slack on every new issue - runs-on: ubuntu-latest - steps: - - name: Convert markdown to slack markdown for issue - uses: LoveToKnow/slackify-markdown-action@v1.0.0 - id: issuemarkdown - with: - text: "[${{github.event.issue.title}}](${{github.event.issue.html_url}}) \n ${{github.event.issue.body}}" - - name: Send info about issue - uses: rtCamp/action-slack-notify@v2 - env: - SLACK_WEBHOOK: ${{secrets.SLACK_GITHUB_NEWISSUEPR}} - SLACK_TITLE: 🐛 New Issue in ${{github.repository}} 🐛 - SLACK_MESSAGE: ${{steps.issuemarkdown.outputs.text}} - MSG_MINIMAL: true + pull_request: + if: github.event_name == 'pull_request_target' && github.actor != 'asyncapi-bot' && github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' + name: Notify slack on every new pull request + runs-on: ubuntu-latest + steps: + - name: Convert markdown to slack markdown for pull request + uses: LoveToKnow/slackify-markdown-action@v1.0.0 + id: prmarkdown + with: + text: "[${{github.event.pull_request.title}}](${{github.event.pull_request.html_url}}) \n ${{github.event.pull_request.body}}" + - name: Send info about pull request + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_WEBHOOK: ${{secrets.SLACK_GITHUB_NEWISSUEPR}} + SLACK_TITLE: 💪 New Pull Request in ${{github.repository}} 💪 + SLACK_MESSAGE: ${{steps.prmarkdown.outputs.text}} + MSG_MINIMAL: true - pull_request: - if: github.event_name == 'pull_request_target' && github.actor != 'asyncapi-bot' && github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' - name: Notify slack on every new pull request - runs-on: ubuntu-latest - steps: - - name: Convert markdown to slack markdown for pull request - uses: LoveToKnow/slackify-markdown-action@v1.0.0 - id: prmarkdown - with: - text: "[${{github.event.pull_request.title}}](${{github.event.pull_request.html_url}}) \n ${{github.event.pull_request.body}}" - - name: Send info about pull request - uses: rtCamp/action-slack-notify@v2 - env: - SLACK_WEBHOOK: ${{secrets.SLACK_GITHUB_NEWISSUEPR}} - SLACK_TITLE: 💪 New Pull Request in ${{github.repository}} 💪 - SLACK_MESSAGE: ${{steps.prmarkdown.outputs.text}} - MSG_MINIMAL: true - - discussion: - if: github.event_name == 'discussion' && github.actor != 'asyncapi-bot' && github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' - name: Notify slack on every new pull request - runs-on: ubuntu-latest - steps: - - name: Convert markdown to slack markdown for pull request - uses: LoveToKnow/slackify-markdown-action@v1.0.0 - id: discussionmarkdown - with: - text: "[${{github.event.discussion.title}}](${{github.event.discussion.html_url}}) \n ${{github.event.discussion.body}}" - - name: Send info about pull request - uses: rtCamp/action-slack-notify@v2 - env: - SLACK_WEBHOOK: ${{secrets.SLACK_GITHUB_NEWISSUEPR}} - SLACK_TITLE: 💬 New Discussion in ${{github.repository}} 💬 - SLACK_MESSAGE: ${{steps.discussionmarkdown.outputs.text}} - MSG_MINIMAL: true + discussion: + if: github.event_name == 'discussion' && github.actor != 'asyncapi-bot' && github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' + name: Notify slack on every new pull request + runs-on: ubuntu-latest + steps: + - name: Convert markdown to slack markdown for pull request + uses: LoveToKnow/slackify-markdown-action@v1.0.0 + id: discussionmarkdown + with: + text: "[${{github.event.discussion.title}}](${{github.event.discussion.html_url}}) \n ${{github.event.discussion.body}}" + - name: Send info about pull request + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_WEBHOOK: ${{secrets.SLACK_GITHUB_NEWISSUEPR}} + SLACK_TITLE: 💬 New Discussion in ${{github.repository}} 💬 + SLACK_MESSAGE: ${{steps.discussionmarkdown.outputs.text}} + MSG_MINIMAL: true diff --git a/.github/workflows/link-check-cron.yml b/.github/workflows/link-check-cron.yml index e992e2d6f..873d4297f 100644 --- a/.github/workflows/link-check-cron.yml +++ b/.github/workflows/link-check-cron.yml @@ -8,30 +8,30 @@ on: schedule: # At 00:00 UTC on every Monday - cron: '0 0 * * 0' - + jobs: External-link-validation-weekly: if: startsWith(github.repository, 'asyncapi/') runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v3 + + # Checks the status of hyperlinks in .md files + - name: Check links + uses: gaurav-nelson/github-action-markdown-link-check@0a51127e9955b855a9bbfa1ff5577f1d1338c9a5 #1.0.14 but pointing to commit for security reasons + with: + use-quiet-mode: 'yes' + use-verbose-mode: 'yes' - # Checks the status of hyperlinks in .md files - - name: Check links - uses: gaurav-nelson/github-action-markdown-link-check@0a51127e9955b855a9bbfa1ff5577f1d1338c9a5 #1.0.14 but pointing to commit for security reasons - with: - use-quiet-mode: 'yes' - use-verbose-mode: 'yes' - - # A configuration file can be included, indicating the properties of the link check action - # More information can be found here: https://github.com/tcort/markdown-link-check#config-file-format - # Create mlc_config.json file in the root of the directory + # A configuration file can be included, indicating the properties of the link check action + # More information can be found here: https://github.com/tcort/markdown-link-check#config-file-format + # Create mlc_config.json file in the root of the directory - - name: Report workflow run status to Slack - uses: 8398a7/action-slack@v3 - with: - status: ${{ job.status }} - fields: repo,action,workflow - env: + - name: Report workflow run status to Slack + uses: 8398a7/action-slack@v3 + with: + status: ${{ job.status }} + fields: repo,action,workflow + env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CI_FAIL_NOTIFY }} - if: failure() # Only, on failure, send a message on the 94_bot-failing-ci slack channel + if: failure() # Only, on failure, send a message on the 94_bot-failing-ci slack channel diff --git a/.github/workflows/link-check-pr.yml b/.github/workflows/link-check-pr.yml index deb425cbf..51f6cf780 100644 --- a/.github/workflows/link-check-pr.yml +++ b/.github/workflows/link-check-pr.yml @@ -3,7 +3,7 @@ name: Check Markdown links -on: +on: pull_request_target: types: [synchronize, ready_for_review, opened, reopened] paths: @@ -13,15 +13,16 @@ jobs: External-link-validation-on-PR: runs-on: ubuntu-latest steps: - - name: Checkout repo - uses: actions/checkout@v3 - - name: Check links - uses: gaurav-nelson/github-action-markdown-link-check@0a51127e9955b855a9bbfa1ff5577f1d1338c9a5 #1.0.14 but pointing to commit for security reasons - with: - use-quiet-mode: 'yes' - use-verbose-mode: 'yes' - check-modified-files-only: 'yes' # Only modified files are checked on PRs - - # A configuration file can be included, indicating the properties of the link check action - # More information can be found here: https://github.com/tcort/markdown-link-check#config-file-format - # Create mlc_config.json file in the root of the directory + - name: Checkout repo + uses: actions/checkout@v3 + - name: Check links + uses: gaurav-nelson/github-action-markdown-link-check@0a51127e9955b855a9bbfa1ff5577f1d1338c9a5 #1.0.14 but pointing to commit for security reasons + with: + use-quiet-mode: 'yes' + use-verbose-mode: 'yes' + check-modified-files-only: 'yes' # Only modified files are checked on PRs + + + # A configuration file can be included, indicating the properties of the link check action + # More information can be found here: https://github.com/tcort/markdown-link-check#config-file-format + # Create mlc_config.json file in the root of the directory diff --git a/.github/workflows/lint-pr-title.yml b/.github/workflows/lint-pr-title.yml index 0440d87e6..c4a942a91 100644 --- a/.github/workflows/lint-pr-title.yml +++ b/.github/workflows/lint-pr-title.yml @@ -1,22 +1,20 @@ # This action is centrally managed in https://github.com/asyncapi/.github/ # Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo - - name: Lint PR title on: pull_request_target: types: [opened, reopened, synchronize, edited, ready_for_review] - + jobs: lint-pr-title: - name: Lint PR title - runs-on: ubuntu-latest - steps: + name: Lint PR title + runs-on: ubuntu-latest + steps: # Since this workflow is REQUIRED for a PR to be mergable, we have to have this 'if' statement in step level instead of job level. - if: ${{ !contains(fromJson('["asyncapi-bot", "dependabot[bot]", "dependabot-preview[bot]", "allcontributors"]'), github.actor) }} - uses: amannn/action-semantic-pull-request@505e44b4f33b4c801f063838b3f053990ee46ea7 #version 4.6.0 + uses: amannn/action-semantic-pull-request@505e44b4f33b4c801f063838b3f053990ee46ea7 #version 4.6.0 id: lint_pr_title env: GITHUB_TOKEN: ${{ secrets.GH_TOKEN}} @@ -24,26 +22,26 @@ jobs: subjectPattern: ^(?![A-Z]).+$ subjectPatternError: | The subject "{subject}" found in the pull request title "{title}" should start with a lowercase character. - - # Comments the error message from the above lint_pr_title action + + # Comments the error message from the above lint_pr_title action - if: ${{ always() && steps.lint_pr_title.outputs.error_message != null && !contains(fromJson('["asyncapi-bot", "dependabot[bot]", "dependabot-preview[bot]", "allcontributors"]'), github.actor)}} name: Comment on PR - uses: marocchino/sticky-pull-request-comment@39c5b5dc7717447d0cba270cd115037d32d28443 #version 2.2 + uses: marocchino/sticky-pull-request-comment@39c5b5dc7717447d0cba270cd115037d32d28443 #version 2.2 with: header: pr-title-lint-error GITHUB_TOKEN: ${{ secrets.GH_TOKEN}} message: | - - We require all PRs to follow [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/). - More details 👇🏼 - ``` - ${{ steps.lint_pr_title.outputs.error_message}} - ``` - # deletes the error comment if the title is correct + + We require all PRs to follow [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/). + More details 👇🏼 + ``` + ${{ steps.lint_pr_title.outputs.error_message}} + ``` + # deletes the error comment if the title is correct - if: ${{ steps.lint_pr_title.outputs.error_message == null }} name: delete the comment - uses: marocchino/sticky-pull-request-comment@39c5b5dc7717447d0cba270cd115037d32d28443 #version 2.2 - with: + uses: marocchino/sticky-pull-request-comment@39c5b5dc7717447d0cba270cd115037d32d28443 #version 2.2 + with: header: pr-title-lint-error delete: true GITHUB_TOKEN: ${{ secrets.GH_TOKEN}} diff --git a/.github/workflows/notify-tsc-members-mention.yml b/.github/workflows/notify-tsc-members-mention.yml index 1cdb371c6..f7abce318 100644 --- a/.github/workflows/notify-tsc-members-mention.yml +++ b/.github/workflows/notify-tsc-members-mention.yml @@ -5,300 +5,299 @@ name: Notify slack and email subscribers whenever TSC members are mentioned in GitHub on: - issue_comment: - types: - - created - - edited - - discussion_comment: - types: - - created - - edited - - issues: - types: - - opened - - reopened + issue_comment: + types: + - created + - edited - pull_request_target: - types: - - opened - - reopened - - ready_for_review + discussion_comment: + types: + - created + - edited - discussion: - types: - - created - - edited + issues: + types: + - opened + - reopened + + pull_request_target: + types: + - opened + - reopened + - ready_for_review + + discussion: + types: + - created + - edited jobs: + issue: + if: github.event_name == 'issues' && contains(github.event.issue.body, '@asyncapi/tsc_members') + name: TSC notification on every new issue + runs-on: ubuntu-latest + steps: + ######### + # Handling Slack notifications + ######### + - name: Convert markdown to slack markdown + uses: LoveToKnow/slackify-markdown-action@v1.0.0 + id: issuemarkdown + with: + text: "[${{github.event.issue.title}}](${{github.event.issue.html_url}}) \n ${{github.event.issue.body}}" + - name: Send info about issue + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_WEBHOOK: ${{secrets.SLACK_TSC_MEMBERS_NOTIFY}} + SLACK_TITLE: 🆘 New issue that requires TSC Members attention 🆘 + SLACK_MESSAGE: ${{steps.issuemarkdown.outputs.text}} + MSG_MINIMAL: true + ######### + # Handling Mailchimp notifications + ######### + - name: Checkout repository + uses: actions/checkout@v2 + - name: Setup Node.js + uses: actions/setup-node@v2 + with: + node-version: 16 + cache: 'npm' + cache-dependency-path: '**/package-lock.json' + - name: Install deps + run: npm install + working-directory: ./.github/workflows/scripts/mailchimp + - name: Send email with MailChimp + uses: actions/github-script@v4 + env: + CALENDAR_ID: ${{ secrets.CALENDAR_ID }} + CALENDAR_SERVICE_ACCOUNT: ${{ secrets.CALENDAR_SERVICE_ACCOUNT }} + MAILCHIMP_API_KEY: ${{ secrets.MAILCHIMP_API_KEY }} + with: + script: | + const sendEmail = require('./.github/workflows/scripts/mailchimp/index.js'); + sendEmail('${{github.event.issue.html_url}}'); - issue: - if: github.event_name == 'issues' && contains(github.event.issue.body, '@asyncapi/tsc_members') - name: TSC notification on every new issue - runs-on: ubuntu-latest - steps: - ######### - # Handling Slack notifications - ######### - - name: Convert markdown to slack markdown - uses: LoveToKnow/slackify-markdown-action@v1.0.0 - id: issuemarkdown - with: - text: "[${{github.event.issue.title}}](${{github.event.issue.html_url}}) \n ${{github.event.issue.body}}" - - name: Send info about issue - uses: rtCamp/action-slack-notify@v2 - env: - SLACK_WEBHOOK: ${{secrets.SLACK_TSC_MEMBERS_NOTIFY}} - SLACK_TITLE: 🆘 New issue that requires TSC Members attention 🆘 - SLACK_MESSAGE: ${{steps.issuemarkdown.outputs.text}} - MSG_MINIMAL: true - ######### - # Handling Mailchimp notifications - ######### - - name: Checkout repository - uses: actions/checkout@v2 - - name: Setup Node.js - uses: actions/setup-node@v2 - with: - node-version: 16 - cache: 'npm' - cache-dependency-path: '**/package-lock.json' - - name: Install deps - run: npm install - working-directory: ./.github/workflows/scripts/mailchimp - - name: Send email with MailChimp - uses: actions/github-script@v4 - env: - CALENDAR_ID: ${{ secrets.CALENDAR_ID }} - CALENDAR_SERVICE_ACCOUNT: ${{ secrets.CALENDAR_SERVICE_ACCOUNT }} - MAILCHIMP_API_KEY: ${{ secrets.MAILCHIMP_API_KEY }} - with: - script: | - const sendEmail = require('./.github/workflows/scripts/mailchimp/index.js'); - sendEmail('${{github.event.issue.html_url}}'); + pull_request: + if: github.event_name == 'pull_request_target' && contains(github.event.pull_request.body, '@asyncapi/tsc_members') + name: TSC notification on every new pull request + runs-on: ubuntu-latest + steps: + ######### + # Handling Slack notifications + ######### + - name: Convert markdown to slack markdown + uses: LoveToKnow/slackify-markdown-action@v1.0.0 + id: prmarkdown + with: + text: "[${{github.event.pull_request.title}}](${{github.event.pull_request.html_url}}) \n ${{github.event.pull_request.body}}" + - name: Send info about pull request + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_WEBHOOK: ${{secrets.SLACK_TSC_MEMBERS_NOTIFY}} + SLACK_TITLE: 🆘 New PR that requires TSC Members attention 🆘 + SLACK_MESSAGE: ${{steps.prmarkdown.outputs.text}} + MSG_MINIMAL: true + ######### + # Handling Mailchimp notifications + ######### + - name: Checkout repository + uses: actions/checkout@v2 + - name: Setup Node.js + uses: actions/setup-node@v2 + with: + node-version: 16 + cache: 'npm' + cache-dependency-path: '**/package-lock.json' + - name: Install deps + run: npm install + working-directory: ./.github/workflows/scripts/mailchimp + - name: Send email with MailChimp + uses: actions/github-script@v4 + env: + CALENDAR_ID: ${{ secrets.CALENDAR_ID }} + CALENDAR_SERVICE_ACCOUNT: ${{ secrets.CALENDAR_SERVICE_ACCOUNT }} + MAILCHIMP_API_KEY: ${{ secrets.MAILCHIMP_API_KEY }} + with: + script: | + const sendEmail = require('./.github/workflows/scripts/mailchimp/index.js'); + sendEmail('${{github.event.pull_request.html_url}}'); - pull_request: - if: github.event_name == 'pull_request_target' && contains(github.event.pull_request.body, '@asyncapi/tsc_members') - name: TSC notification on every new pull request - runs-on: ubuntu-latest - steps: - ######### - # Handling Slack notifications - ######### - - name: Convert markdown to slack markdown - uses: LoveToKnow/slackify-markdown-action@v1.0.0 - id: prmarkdown - with: - text: "[${{github.event.pull_request.title}}](${{github.event.pull_request.html_url}}) \n ${{github.event.pull_request.body}}" - - name: Send info about pull request - uses: rtCamp/action-slack-notify@v2 - env: - SLACK_WEBHOOK: ${{secrets.SLACK_TSC_MEMBERS_NOTIFY}} - SLACK_TITLE: 🆘 New PR that requires TSC Members attention 🆘 - SLACK_MESSAGE: ${{steps.prmarkdown.outputs.text}} - MSG_MINIMAL: true - ######### - # Handling Mailchimp notifications - ######### - - name: Checkout repository - uses: actions/checkout@v2 - - name: Setup Node.js - uses: actions/setup-node@v2 - with: - node-version: 16 - cache: 'npm' - cache-dependency-path: '**/package-lock.json' - - name: Install deps - run: npm install - working-directory: ./.github/workflows/scripts/mailchimp - - name: Send email with MailChimp - uses: actions/github-script@v4 - env: - CALENDAR_ID: ${{ secrets.CALENDAR_ID }} - CALENDAR_SERVICE_ACCOUNT: ${{ secrets.CALENDAR_SERVICE_ACCOUNT }} - MAILCHIMP_API_KEY: ${{ secrets.MAILCHIMP_API_KEY }} - with: - script: | - const sendEmail = require('./.github/workflows/scripts/mailchimp/index.js'); - sendEmail('${{github.event.pull_request.html_url}}'); - - discussion: - if: github.event_name == 'discussion' && contains(github.event.discussion.body, '@asyncapi/tsc_members') - name: TSC notification on every new discussion - runs-on: ubuntu-latest - steps: - ######### - # Handling Slack notifications - ######### - - name: Convert markdown to slack markdown - uses: LoveToKnow/slackify-markdown-action@v1.0.0 - id: discussionmarkdown - with: - text: "[${{github.event.discussion.title}}](${{github.event.discussion.html_url}}) \n ${{github.event.discussion.body}}" - - name: Send info about pull request - uses: rtCamp/action-slack-notify@v2 - env: - SLACK_WEBHOOK: ${{secrets.SLACK_TSC_MEMBERS_NOTIFY}} - SLACK_TITLE: 🆘 New discussion that requires TSC Members attention 🆘 - SLACK_MESSAGE: ${{steps.discussionmarkdown.outputs.text}} - MSG_MINIMAL: true - ######### - # Handling Mailchimp notifications - ######### - - name: Checkout repository - uses: actions/checkout@v2 - - name: Setup Node.js - uses: actions/setup-node@v2 - with: - node-version: 16 - cache: 'npm' - cache-dependency-path: '**/package-lock.json' - - name: Install deps - run: npm install - working-directory: ./.github/workflows/scripts/mailchimp - - name: Send email with MailChimp - uses: actions/github-script@v4 - env: - CALENDAR_ID: ${{ secrets.CALENDAR_ID }} - CALENDAR_SERVICE_ACCOUNT: ${{ secrets.CALENDAR_SERVICE_ACCOUNT }} - MAILCHIMP_API_KEY: ${{ secrets.MAILCHIMP_API_KEY }} - with: - script: | - const sendEmail = require('./.github/workflows/scripts/mailchimp/index.js'); - sendEmail('${{github.event.discussion.html_url}}'); + discussion: + if: github.event_name == 'discussion' && contains(github.event.discussion.body, '@asyncapi/tsc_members') + name: TSC notification on every new discussion + runs-on: ubuntu-latest + steps: + ######### + # Handling Slack notifications + ######### + - name: Convert markdown to slack markdown + uses: LoveToKnow/slackify-markdown-action@v1.0.0 + id: discussionmarkdown + with: + text: "[${{github.event.discussion.title}}](${{github.event.discussion.html_url}}) \n ${{github.event.discussion.body}}" + - name: Send info about pull request + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_WEBHOOK: ${{secrets.SLACK_TSC_MEMBERS_NOTIFY}} + SLACK_TITLE: 🆘 New discussion that requires TSC Members attention 🆘 + SLACK_MESSAGE: ${{steps.discussionmarkdown.outputs.text}} + MSG_MINIMAL: true + ######### + # Handling Mailchimp notifications + ######### + - name: Checkout repository + uses: actions/checkout@v2 + - name: Setup Node.js + uses: actions/setup-node@v2 + with: + node-version: 16 + cache: 'npm' + cache-dependency-path: '**/package-lock.json' + - name: Install deps + run: npm install + working-directory: ./.github/workflows/scripts/mailchimp + - name: Send email with MailChimp + uses: actions/github-script@v4 + env: + CALENDAR_ID: ${{ secrets.CALENDAR_ID }} + CALENDAR_SERVICE_ACCOUNT: ${{ secrets.CALENDAR_SERVICE_ACCOUNT }} + MAILCHIMP_API_KEY: ${{ secrets.MAILCHIMP_API_KEY }} + with: + script: | + const sendEmail = require('./.github/workflows/scripts/mailchimp/index.js'); + sendEmail('${{github.event.discussion.html_url}}'); - issue_comment: - if: ${{ github.event_name == 'issue_comment' && !github.event.issue.pull_request && contains(github.event.comment.body, '@asyncapi/tsc_members') }} - name: TSC notification on every new comment in issue - runs-on: ubuntu-latest - steps: - ######### - # Handling Slack notifications - ######### - - name: Convert markdown to slack markdown - uses: LoveToKnow/slackify-markdown-action@v1.0.0 - id: issuemarkdown - with: - text: "[${{github.event.issue.title}}](${{github.event.comment.html_url}}) \n ${{github.event.comment.body}}" - - name: Send info about issue comment - uses: rtCamp/action-slack-notify@v2 - env: - SLACK_WEBHOOK: ${{secrets.SLACK_TSC_MEMBERS_NOTIFY}} - SLACK_TITLE: 🆘 New comment under existing issue that requires TSC Members attention 🆘 - SLACK_MESSAGE: ${{steps.issuemarkdown.outputs.text}} - MSG_MINIMAL: true - ######### - # Handling Mailchimp notifications - ######### - - name: Checkout repository - uses: actions/checkout@v2 - - name: Setup Node.js - uses: actions/setup-node@v2 - with: - node-version: 16 - cache: 'npm' - cache-dependency-path: '**/package-lock.json' - - name: Install deps - run: npm install - working-directory: ./.github/workflows/scripts/mailchimp - - name: Send email with MailChimp - uses: actions/github-script@v4 - env: - CALENDAR_ID: ${{ secrets.CALENDAR_ID }} - CALENDAR_SERVICE_ACCOUNT: ${{ secrets.CALENDAR_SERVICE_ACCOUNT }} - MAILCHIMP_API_KEY: ${{ secrets.MAILCHIMP_API_KEY }} - with: - script: | - const sendEmail = require('./.github/workflows/scripts/mailchimp/index.js'); - sendEmail('${{github.event.comment.html_url}}'); + issue_comment: + if: ${{ github.event_name == 'issue_comment' && !github.event.issue.pull_request && contains(github.event.comment.body, '@asyncapi/tsc_members') }} + name: TSC notification on every new comment in issue + runs-on: ubuntu-latest + steps: + ######### + # Handling Slack notifications + ######### + - name: Convert markdown to slack markdown + uses: LoveToKnow/slackify-markdown-action@v1.0.0 + id: issuemarkdown + with: + text: "[${{github.event.issue.title}}](${{github.event.comment.html_url}}) \n ${{github.event.comment.body}}" + - name: Send info about issue comment + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_WEBHOOK: ${{secrets.SLACK_TSC_MEMBERS_NOTIFY}} + SLACK_TITLE: 🆘 New comment under existing issue that requires TSC Members attention 🆘 + SLACK_MESSAGE: ${{steps.issuemarkdown.outputs.text}} + MSG_MINIMAL: true + ######### + # Handling Mailchimp notifications + ######### + - name: Checkout repository + uses: actions/checkout@v2 + - name: Setup Node.js + uses: actions/setup-node@v2 + with: + node-version: 16 + cache: 'npm' + cache-dependency-path: '**/package-lock.json' + - name: Install deps + run: npm install + working-directory: ./.github/workflows/scripts/mailchimp + - name: Send email with MailChimp + uses: actions/github-script@v4 + env: + CALENDAR_ID: ${{ secrets.CALENDAR_ID }} + CALENDAR_SERVICE_ACCOUNT: ${{ secrets.CALENDAR_SERVICE_ACCOUNT }} + MAILCHIMP_API_KEY: ${{ secrets.MAILCHIMP_API_KEY }} + with: + script: | + const sendEmail = require('./.github/workflows/scripts/mailchimp/index.js'); + sendEmail('${{github.event.comment.html_url}}'); - pr_comment: - if: github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, '@asyncapi/tsc_members') - name: TSC notification on every new comment in pr - runs-on: ubuntu-latest - steps: - ######### - # Handling Slack notifications - ######### - - name: Convert markdown to slack markdown - uses: LoveToKnow/slackify-markdown-action@v1.0.0 - id: prmarkdown - with: - text: "[${{github.event.issue.title}}](${{github.event.comment.html_url}}) \n ${{github.event.comment.body}}" - - name: Send info about PR comment - uses: rtCamp/action-slack-notify@v2 - env: - SLACK_WEBHOOK: ${{secrets.SLACK_TSC_MEMBERS_NOTIFY}} - SLACK_TITLE: 🆘 New comment under existing PR that requires TSC Members attention 🆘 - SLACK_MESSAGE: ${{steps.prmarkdown.outputs.text}} - MSG_MINIMAL: true - ######### - # Handling Mailchimp notifications - ######### - - name: Checkout repository - uses: actions/checkout@v2 - - name: Setup Node.js - uses: actions/setup-node@v2 - with: - node-version: 16 - cache: 'npm' - cache-dependency-path: '**/package-lock.json' - - name: Install deps - run: npm install - working-directory: ./.github/workflows/scripts/mailchimp - - name: Send email with MailChimp - uses: actions/github-script@v4 - env: - CALENDAR_ID: ${{ secrets.CALENDAR_ID }} - CALENDAR_SERVICE_ACCOUNT: ${{ secrets.CALENDAR_SERVICE_ACCOUNT }} - MAILCHIMP_API_KEY: ${{ secrets.MAILCHIMP_API_KEY }} - with: - script: | - const sendEmail = require('./.github/workflows/scripts/mailchimp/index.js'); - sendEmail('${{github.event.comment.html_url}}'); + pr_comment: + if: github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, '@asyncapi/tsc_members') + name: TSC notification on every new comment in pr + runs-on: ubuntu-latest + steps: + ######### + # Handling Slack notifications + ######### + - name: Convert markdown to slack markdown + uses: LoveToKnow/slackify-markdown-action@v1.0.0 + id: prmarkdown + with: + text: "[${{github.event.issue.title}}](${{github.event.comment.html_url}}) \n ${{github.event.comment.body}}" + - name: Send info about PR comment + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_WEBHOOK: ${{secrets.SLACK_TSC_MEMBERS_NOTIFY}} + SLACK_TITLE: 🆘 New comment under existing PR that requires TSC Members attention 🆘 + SLACK_MESSAGE: ${{steps.prmarkdown.outputs.text}} + MSG_MINIMAL: true + ######### + # Handling Mailchimp notifications + ######### + - name: Checkout repository + uses: actions/checkout@v2 + - name: Setup Node.js + uses: actions/setup-node@v2 + with: + node-version: 16 + cache: 'npm' + cache-dependency-path: '**/package-lock.json' + - name: Install deps + run: npm install + working-directory: ./.github/workflows/scripts/mailchimp + - name: Send email with MailChimp + uses: actions/github-script@v4 + env: + CALENDAR_ID: ${{ secrets.CALENDAR_ID }} + CALENDAR_SERVICE_ACCOUNT: ${{ secrets.CALENDAR_SERVICE_ACCOUNT }} + MAILCHIMP_API_KEY: ${{ secrets.MAILCHIMP_API_KEY }} + with: + script: | + const sendEmail = require('./.github/workflows/scripts/mailchimp/index.js'); + sendEmail('${{github.event.comment.html_url}}'); - discussion_comment: - if: github.event_name == 'discussion_comment' && contains(github.event.comment.body, '@asyncapi/tsc_members') - name: TSC notification on every new comment in discussion - runs-on: ubuntu-latest - steps: - ######### - # Handling Slack notifications - ######### - - name: Convert markdown to slack markdown - uses: LoveToKnow/slackify-markdown-action@v1.0.0 - id: discussionmarkdown - with: - text: "[${{github.event.discussion.title}}](${{github.event.comment.html_url}}) \n ${{github.event.comment.body}}" - - name: Send info about discussion comment - uses: rtCamp/action-slack-notify@v2 - env: - SLACK_WEBHOOK: ${{secrets.SLACK_TSC_MEMBERS_NOTIFY}} - SLACK_TITLE: 🆘 New comment under existing discussion that requires TSC Members attention 🆘 - SLACK_MESSAGE: ${{steps.discussionmarkdown.outputs.text}} - MSG_MINIMAL: true - ######### - # Handling Mailchimp notifications - ######### - - name: Checkout repository - uses: actions/checkout@v2 - - name: Setup Node.js - uses: actions/setup-node@v2 - with: - node-version: 16 - cache: 'npm' - cache-dependency-path: '**/package-lock.json' - - name: Install deps - run: npm install - working-directory: ./.github/workflows/scripts/mailchimp - - name: Send email with MailChimp - uses: actions/github-script@v4 - env: - CALENDAR_ID: ${{ secrets.CALENDAR_ID }} - CALENDAR_SERVICE_ACCOUNT: ${{ secrets.CALENDAR_SERVICE_ACCOUNT }} - MAILCHIMP_API_KEY: ${{ secrets.MAILCHIMP_API_KEY }} - with: - script: | - const sendEmail = require('./.github/workflows/scripts/mailchimp/index.js'); - sendEmail('${{github.event.comment.html_url}}'); \ No newline at end of file + discussion_comment: + if: github.event_name == 'discussion_comment' && contains(github.event.comment.body, '@asyncapi/tsc_members') + name: TSC notification on every new comment in discussion + runs-on: ubuntu-latest + steps: + ######### + # Handling Slack notifications + ######### + - name: Convert markdown to slack markdown + uses: LoveToKnow/slackify-markdown-action@v1.0.0 + id: discussionmarkdown + with: + text: "[${{github.event.discussion.title}}](${{github.event.comment.html_url}}) \n ${{github.event.comment.body}}" + - name: Send info about discussion comment + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_WEBHOOK: ${{secrets.SLACK_TSC_MEMBERS_NOTIFY}} + SLACK_TITLE: 🆘 New comment under existing discussion that requires TSC Members attention 🆘 + SLACK_MESSAGE: ${{steps.discussionmarkdown.outputs.text}} + MSG_MINIMAL: true + ######### + # Handling Mailchimp notifications + ######### + - name: Checkout repository + uses: actions/checkout@v2 + - name: Setup Node.js + uses: actions/setup-node@v2 + with: + node-version: 16 + cache: 'npm' + cache-dependency-path: '**/package-lock.json' + - name: Install deps + run: npm install + working-directory: ./.github/workflows/scripts/mailchimp + - name: Send email with MailChimp + uses: actions/github-script@v4 + env: + CALENDAR_ID: ${{ secrets.CALENDAR_ID }} + CALENDAR_SERVICE_ACCOUNT: ${{ secrets.CALENDAR_SERVICE_ACCOUNT }} + MAILCHIMP_API_KEY: ${{ secrets.MAILCHIMP_API_KEY }} + with: + script: | + const sendEmail = require('./.github/workflows/scripts/mailchimp/index.js'); + sendEmail('${{github.event.comment.html_url}}'); From d5c89607624890d2b2c6bd547d3c29500ed04a2d Mon Sep 17 00:00:00 2001 From: Tenshi Codes <116377630+codingtenshi@users.noreply.github.com> Date: Mon, 14 Nov 2022 20:03:02 +0100 Subject: [PATCH 03/37] ci: remove not needed workflow (#872) --- .github/workflows/bump.yml | 34 -------- .github/workflows/if-go-pr-testing.yml | 69 ---------------- .github/workflows/if-nodejs-pr-testing.yml | 61 -------------- .github/workflows/if-nodejs-release.yml | 83 -------------------- .github/workflows/if-nodejs-version-bump.yml | 49 ------------ 5 files changed, 296 deletions(-) delete mode 100644 .github/workflows/bump.yml delete mode 100644 .github/workflows/if-go-pr-testing.yml delete mode 100644 .github/workflows/if-nodejs-pr-testing.yml delete mode 100644 .github/workflows/if-nodejs-release.yml delete mode 100644 .github/workflows/if-nodejs-version-bump.yml diff --git a/.github/workflows/bump.yml b/.github/workflows/bump.yml deleted file mode 100644 index 68daa7c0c..000000000 --- a/.github/workflows/bump.yml +++ /dev/null @@ -1,34 +0,0 @@ -# This action is centrally managed in https://github.com/asyncapi/.github/ -# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo - -# Purpose of this action is to update npm package in libraries that use it. It is like dependabot for asyncapi npm modules only. -# It runs in a repo after merge of release commit and searches for other packages that use released package. Every found package gets updated with lates version - -name: Bump package version in dependent repos - if Node project - -on: - # It cannot run on release event as when release is created then version is not yet bumped in package.json - # This means we cannot extract easily latest version and have a risk that package is not yet on npm - push: - branches: - - master - -jobs: - bump-in-dependent-projects: - name: Bump this package in repositories that depend on it - if: startsWith(github.event.commits[0].message, 'chore(release):') - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@v2 - - name: Check if Node.js project and has package.json - id: packagejson - run: test -e ./package.json && echo "::set-output name=exists::true" || echo "::set-output name=exists::false" - - if: steps.packagejson.outputs.exists == 'true' - name: Bumping latest version of this package in other repositories - uses: derberg/npm-dependency-manager-for-your-github-org@v4 - with: - github_token: ${{ secrets.GH_TOKEN }} - committer_username: asyncapi-bot - committer_email: info@asyncapi.io - repos_to_ignore: html-template # this is temporary until react component releases 1.0, then it can be removed diff --git a/.github/workflows/if-go-pr-testing.yml b/.github/workflows/if-go-pr-testing.yml deleted file mode 100644 index 606e689b3..000000000 --- a/.github/workflows/if-go-pr-testing.yml +++ /dev/null @@ -1,69 +0,0 @@ -# This action is centrally managed in https://github.com/asyncapi/.github/ -# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo - -# It does magic only if there is go.mod file in the root of the project -name: PR testing - if Go project - -on: - pull_request: - types: [opened, reopened, synchronize, ready_for_review] - -jobs: - lint-go-pr: - name: Lint Go PR - runs-on: ubuntu-latest - steps: - - if: "github.event.pull_request.draft == false &&!((github.actor == 'asyncapi-bot' && startsWith(github.event.pull_request.title, 'ci: update global workflows')) || (github.actor == 'asyncapi-bot' && startsWith(github.event.pull_request.title, 'chore(release):')) || (github.actor == 'allcontributors' && startsWith(github.event.pull_request.title, 'docs: add')))" - id: should_run - name: Should Run - run: echo "::set-output name=shouldrun::true" - - if: steps.should_run.outputs.shouldrun == 'true' - name: Checkout repository - uses: actions/checkout@v2 - - if: steps.should_run.outputs.shouldrun == 'true' - name: Check if Go project and has go.mod - id: gomod - run: test -e ./go.mod && echo "::set-output name=exists::true" || echo "::set-output name=exists::false" - shell: bash - - if: steps.gomod.outputs.exists == 'true' - name: Setup Go - uses: actions/setup-go@v2.1.3 - with: - go-version: 1.16 - - if: steps.gomod.outputs.exists == 'true' - name: golangci-lint - uses: golangci/golangci-lint-action@v2 # golangci-lint version extracted from go.mod. `latest` if missing. - with: - skip-go-installation: true # we wanna control the version of Go in use - - test-go-pr: - name: Test Go PR - ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - steps: - - if: "github.event.pull_request.draft == false &&!((github.actor == 'asyncapi-bot' && startsWith(github.event.pull_request.title, 'ci: update global workflows')) || (github.actor == 'asyncapi-bot' && startsWith(github.event.pull_request.title, 'chore(release):')) || (github.actor == 'allcontributors' && startsWith(github.event.pull_request.title, 'docs: add')))" - id: should_run - name: Should Run - run: echo "::set-output name=shouldrun::true" - - if: steps.should_run.outputs.shouldrun == 'true' - name: Checkout repository - uses: actions/checkout@v2 - - if: steps.should_run.outputs.shouldrun == 'true' - name: Check if Go project and has go.mod - id: gomod - run: test -e ./go.mod && echo "::set-output name=exists::true" || echo "::set-output name=exists::false" - shell: bash - - if: steps.gomod.outputs.exists == 'true' - name: Setup Go - uses: actions/setup-go@v2.1.3 - with: - go-version: 1.16 - - if: steps.gomod.outputs.exists == 'true' - name: Build - run: go build -v ./... - - if: steps.gomod.outputs.exists == 'true' - name: Test - run: go test -v ./... - diff --git a/.github/workflows/if-nodejs-pr-testing.yml b/.github/workflows/if-nodejs-pr-testing.yml deleted file mode 100644 index 1dcccd320..000000000 --- a/.github/workflows/if-nodejs-pr-testing.yml +++ /dev/null @@ -1,61 +0,0 @@ -# This action is centrally managed in https://github.com/asyncapi/.github/ -# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo - -# It does magic only if there is package.json file in the root of the project -name: PR testing - if Node project - -on: - pull_request: - types: [opened, reopened, synchronize, ready_for_review] - -jobs: - test-nodejs-pr: - name: Test NodeJS PR - ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - steps: - - if: "github.event.pull_request.draft == false &&!((github.actor == 'asyncapi-bot' && startsWith(github.event.pull_request.title, 'ci: update global workflows')) || (github.actor == 'asyncapi-bot' && startsWith(github.event.pull_request.title, 'chore(release):')) || (github.actor == 'allcontributors' && startsWith(github.event.pull_request.title, 'docs: add')))" - id: should_run - name: Should Run - run: echo "::set-output name=shouldrun::true" - - if: steps.should_run.outputs.shouldrun == 'true' - name: Set git to use LF #to once and for all finish neverending fight between Unix and Windows - run: | - git config --global core.autocrlf false - git config --global core.eol lf - - if: steps.should_run.outputs.shouldrun == 'true' - name: Checkout repository - uses: actions/checkout@v2 - - if: steps.should_run.outputs.shouldrun == 'true' - name: Check if Node.js project and has package.json - id: packagejson - run: test -e ./package.json && echo "::set-output name=exists::true" || echo "::set-output name=exists::false" - shell: bash - - if: steps.packagejson.outputs.exists == 'true' - name: Setup Node.js - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: 'npm' - cache-dependency-path: '**/package-lock.json' - - if: steps.packagejson.outputs.exists == 'true' - name: Install dependencies - id: first-installation - run: npm install --loglevel verbose - continue-on-error: true - - if: steps.first-installation.outputs.status == 'failure' && steps.packagejson.outputs.exists == 'true' - name: Clear NPM cache and install deps again - run: | - npm cache clean --force - npm install --loglevel verbose - - if: steps.packagejson.outputs.exists == 'true' - name: Test - run: npm test - - if: steps.packagejson.outputs.exists == 'true' - name: Run linter - run: npm run lint - - if: steps.packagejson.outputs.exists == 'true' - name: Run release assets generation to make sure PR does not break it - run: npm run generate:assets diff --git a/.github/workflows/if-nodejs-release.yml b/.github/workflows/if-nodejs-release.yml deleted file mode 100644 index 4a34feb03..000000000 --- a/.github/workflows/if-nodejs-release.yml +++ /dev/null @@ -1,83 +0,0 @@ -# This action is centrally managed in https://github.com/asyncapi/.github/ -# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo - -# It does magic only if there is package.json file in the root of the project -name: Release - if Node project - -on: - push: - branches: - - master - # below lines are not enough to have release supported for these branches - # make sure configuration of `semantic-release` package mentions these branches - - next-spec - - next-major-spec - -jobs: - - test-nodejs: - name: Test NodeJS release on ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - steps: - - name: Set git to use LF #to once and for all finish neverending fight between Unix and Windows - run: | - git config --global core.autocrlf false - git config --global core.eol lf - - name: Checkout repository - uses: actions/checkout@v2 - - name: Check if Node.js project and has package.json - id: packagejson - run: test -e ./package.json && echo "::set-output name=exists::true" || echo "::set-output name=exists::false" - shell: bash - - if: steps.packagejson.outputs.exists == 'true' - name: Setup Node.js - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: 'npm' - cache-dependency-path: '**/package-lock.json' - - if: steps.packagejson.outputs.exists == 'true' - name: Install dependencies - run: npm install - - if: steps.packagejson.outputs.exists == 'true' - name: Run test - run: npm test - - release: - needs: [test-nodejs] - name: Publish to any of NPM, Github, and Docker Hub - runs-on: ubuntu-latest - steps: - - name: Set git to use LF #to once and for all finish neverending fight between Unix and Windows - run: | - git config --global core.autocrlf false - git config --global core.eol lf - - name: Checkout repository - uses: actions/checkout@v2 - - name: Check if Node.js project and has package.json - id: packagejson - run: test -e ./package.json && echo "::set-output name=exists::true" || echo "::set-output name=exists::false" - - if: steps.packagejson.outputs.exists == 'true' - name: Setup Node.js - uses: actions/setup-node@v1 - with: - node-version: 14 - - if: steps.packagejson.outputs.exists == 'true' - name: Install dependencies - run: npm install - - if: steps.packagejson.outputs.exists == 'true' - name: Publish to any of NPM, Github, and Docker Hub - id: release - env: - GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - GIT_AUTHOR_NAME: asyncapi-bot - GIT_AUTHOR_EMAIL: info@asyncapi.io - GIT_COMMITTER_NAME: asyncapi-bot - GIT_COMMITTER_EMAIL: info@asyncapi.io - run: npm run release diff --git a/.github/workflows/if-nodejs-version-bump.yml b/.github/workflows/if-nodejs-version-bump.yml deleted file mode 100644 index 721caa9d7..000000000 --- a/.github/workflows/if-nodejs-version-bump.yml +++ /dev/null @@ -1,49 +0,0 @@ -# This action is centrally managed in https://github.com/asyncapi/.github/ -# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo - -# It does magic only if there is package.json file in the root of the project -name: Version bump - if Node.js project - -on: - release: - types: - - published - -jobs: - version_bump: - name: Generate assets and bump NodeJS - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v2 - with: - # target branch of release. More info https://docs.github.com/en/rest/reference/repos#releases - # in case release is created from release branch then we need to checkout from given branch - # if @semantic-release/github is used to publish, the minimum version is 7.2.0 for proper working - ref: ${{ github.event.release.target_commitish }} - - name: Check if Node.js project and has package.json - id: packagejson - run: test -e ./package.json && echo "::set-output name=exists::true" || echo "::set-output name=exists::false" - - if: steps.packagejson.outputs.exists == 'true' - name: Install dependencies - run: npm install - - if: steps.packagejson.outputs.exists == 'true' - name: Assets generation - run: npm run generate:assets - - if: steps.packagejson.outputs.exists == 'true' - name: Bump version in package.json - # There is no need to substract "v" from the tag as version script handles it - # When adding "bump:version" script in package.json, make sure no tags are added by default (--no-git-tag-version) as they are already added by release workflow - # When adding "bump:version" script in package.json, make sure --allow-same-version is set in case someone forgot and updated package.json manually and we want to avoide this action to fail and raise confusion - run: VERSION=${{github.event.release.tag_name}} npm run bump:version - - if: steps.packagejson.outputs.exists == 'true' - name: Create Pull Request with updated asset files including package.json - uses: peter-evans/create-pull-request@v3 - with: - token: ${{ secrets.GH_TOKEN }} - commit-message: 'chore(release): ${{github.event.release.tag_name}}' - committer: asyncapi-bot - author: asyncapi-bot - title: 'chore(release): ${{github.event.release.tag_name}}' - body: 'Version bump in package.json for release [${{github.event.release.tag_name}}](${{github.event.release.html_url}})' - branch: version-bump/${{github.event.release.tag_name}} \ No newline at end of file From eb8bb65f7adff9df78082d47d7c67a94f5a11838 Mon Sep 17 00:00:00 2001 From: Lukasz Gornicki Date: Thu, 17 Nov 2022 16:31:06 +0100 Subject: [PATCH 04/37] chore: fix example for operation security (#873) --- .gitignore | 3 ++- examples/operation-security.yml | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 55371e5c8..a85bd49c7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules -.vscode \ No newline at end of file +.vscode +.github/.DS_Store diff --git a/examples/operation-security.yml b/examples/operation-security.yml index f853072b2..b0d234bf4 100644 --- a/examples/operation-security.yml +++ b/examples/operation-security.yml @@ -22,8 +22,8 @@ channels: enum: - application/json security: - petstore_auth: - - subscribe:auth_revocations + - petstore_auth: + - subscribe:auth_revocations components: messages: message: From 90e6a99fe8e57115f2f33d85d9d7bc7dc8b94d2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Urba=C5=84czyk?= Date: Tue, 22 Nov 2022 14:26:04 +0100 Subject: [PATCH 05/37] chore: update asyncapi versions in the social-media example (#876) --- examples/social-media/backend/asyncapi.yaml | 2 +- examples/social-media/comments-service/asyncapi.yaml | 2 +- examples/social-media/frontend/asyncapi.yaml | 2 +- examples/social-media/notification-service/asyncapi.yaml | 2 +- examples/social-media/public-api/asyncapi.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/social-media/backend/asyncapi.yaml b/examples/social-media/backend/asyncapi.yaml index 5f7cb94e5..b2f6a9a31 100644 --- a/examples/social-media/backend/asyncapi.yaml +++ b/examples/social-media/backend/asyncapi.yaml @@ -1,4 +1,4 @@ -asyncapi: 2.2.0 +asyncapi: 2.5.0 info: title: Website Backend diff --git a/examples/social-media/comments-service/asyncapi.yaml b/examples/social-media/comments-service/asyncapi.yaml index ce8f93a9e..308c10b03 100644 --- a/examples/social-media/comments-service/asyncapi.yaml +++ b/examples/social-media/comments-service/asyncapi.yaml @@ -1,4 +1,4 @@ -asyncapi: 2.2.0 +asyncapi: 2.5.0 info: title: Comments Service diff --git a/examples/social-media/frontend/asyncapi.yaml b/examples/social-media/frontend/asyncapi.yaml index 2837fb6ff..1f46ede41 100644 --- a/examples/social-media/frontend/asyncapi.yaml +++ b/examples/social-media/frontend/asyncapi.yaml @@ -1,4 +1,4 @@ -asyncapi: 2.2.0 +asyncapi: 2.5.0 info: title: Website WebSocket Client diff --git a/examples/social-media/notification-service/asyncapi.yaml b/examples/social-media/notification-service/asyncapi.yaml index be78362c9..0789a7b6b 100644 --- a/examples/social-media/notification-service/asyncapi.yaml +++ b/examples/social-media/notification-service/asyncapi.yaml @@ -1,4 +1,4 @@ -asyncapi: 2.2.0 +asyncapi: 2.5.0 info: title: Notifications Service diff --git a/examples/social-media/public-api/asyncapi.yaml b/examples/social-media/public-api/asyncapi.yaml index 0a7cdde79..f97ee0b78 100644 --- a/examples/social-media/public-api/asyncapi.yaml +++ b/examples/social-media/public-api/asyncapi.yaml @@ -1,4 +1,4 @@ -asyncapi: 2.2.0 +asyncapi: 2.5.0 info: title: Public API From 77cb1574631fa0494a1018eb71500abf21086161 Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Wed, 23 Nov 2022 18:37:58 +0100 Subject: [PATCH 06/37] ci: update generic workflows (#877) --- .../workflows/notify-tsc-members-mention.yml | 18 ++++++------------ .../workflows/scripts/mailchimp/htmlContent.js | 4 ++-- .github/workflows/scripts/mailchimp/index.js | 6 +++--- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/.github/workflows/notify-tsc-members-mention.yml b/.github/workflows/notify-tsc-members-mention.yml index f7abce318..e681c18a0 100644 --- a/.github/workflows/notify-tsc-members-mention.yml +++ b/.github/workflows/notify-tsc-members-mention.yml @@ -8,28 +8,22 @@ on: issue_comment: types: - created - - edited discussion_comment: types: - created - - edited issues: types: - opened - - reopened pull_request_target: types: - opened - - reopened - - ready_for_review discussion: types: - created - - edited jobs: issue: @@ -75,7 +69,7 @@ jobs: with: script: | const sendEmail = require('./.github/workflows/scripts/mailchimp/index.js'); - sendEmail('${{github.event.issue.html_url}}'); + sendEmail('${{github.event.issue.html_url}}', '${{github.event.issue.title}}'); pull_request: if: github.event_name == 'pull_request_target' && contains(github.event.pull_request.body, '@asyncapi/tsc_members') @@ -120,7 +114,7 @@ jobs: with: script: | const sendEmail = require('./.github/workflows/scripts/mailchimp/index.js'); - sendEmail('${{github.event.pull_request.html_url}}'); + sendEmail('${{github.event.pull_request.html_url}}', '${{github.event.pull_request.title}}'); discussion: if: github.event_name == 'discussion' && contains(github.event.discussion.body, '@asyncapi/tsc_members') @@ -165,7 +159,7 @@ jobs: with: script: | const sendEmail = require('./.github/workflows/scripts/mailchimp/index.js'); - sendEmail('${{github.event.discussion.html_url}}'); + sendEmail('${{github.event.discussion.html_url}}', '${{github.event.discussion.title}}'); issue_comment: if: ${{ github.event_name == 'issue_comment' && !github.event.issue.pull_request && contains(github.event.comment.body, '@asyncapi/tsc_members') }} @@ -210,7 +204,7 @@ jobs: with: script: | const sendEmail = require('./.github/workflows/scripts/mailchimp/index.js'); - sendEmail('${{github.event.comment.html_url}}'); + sendEmail('${{github.event.comment.html_url}}', '${{github.event.issue.title}}'); pr_comment: if: github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, '@asyncapi/tsc_members') @@ -255,7 +249,7 @@ jobs: with: script: | const sendEmail = require('./.github/workflows/scripts/mailchimp/index.js'); - sendEmail('${{github.event.comment.html_url}}'); + sendEmail('${{github.event.comment.html_url}}', '${{github.event.issue.title}}'); discussion_comment: if: github.event_name == 'discussion_comment' && contains(github.event.comment.body, '@asyncapi/tsc_members') @@ -300,4 +294,4 @@ jobs: with: script: | const sendEmail = require('./.github/workflows/scripts/mailchimp/index.js'); - sendEmail('${{github.event.comment.html_url}}'); + sendEmail('${{github.event.comment.html_url}}', '${{github.event.discussion.title}}'); diff --git a/.github/workflows/scripts/mailchimp/htmlContent.js b/.github/workflows/scripts/mailchimp/htmlContent.js index e3eadc979..d132c72f1 100644 --- a/.github/workflows/scripts/mailchimp/htmlContent.js +++ b/.github/workflows/scripts/mailchimp/htmlContent.js @@ -2,7 +2,7 @@ * This code is centrally managed in https://github.com/asyncapi/.github/ * Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo */ -module.exports = (link) => { +module.exports = (link, title) => { return ` @@ -386,7 +386,7 @@ There is a new topic at AsyncAPI Initiative that requires Technical Steering Com
Please have a look if it is just something you need to be aware of, or maybe your vote is needed.
-Click here to see more details on GitHub. +Topic: ${ title }. diff --git a/.github/workflows/scripts/mailchimp/index.js b/.github/workflows/scripts/mailchimp/index.js index a7b6f78fb..387176b41 100644 --- a/.github/workflows/scripts/mailchimp/index.js +++ b/.github/workflows/scripts/mailchimp/index.js @@ -10,7 +10,7 @@ const htmlContent = require('./htmlContent.js'); * Sending API request to mailchimp to schedule email to subscribers * Input is the URL to issue/discussion or other resource */ -module.exports = async (link) => { +module.exports = async (link, title) => { let newCampaign; @@ -32,7 +32,7 @@ module.exports = async (link) => { } }, settings: { - subject_line: 'AsyncAPI TSC members attention required', + subject_line: `TSC attention required: ${ title }`, preview_text: 'Check out the latest topic that TSC members have to be aware of', title: `New topic info - ${ new Date(Date.now()).toUTCString()}`, from_name: 'AsyncAPI Initiative', @@ -47,7 +47,7 @@ module.exports = async (link) => { * Content of the email is added separately after campaign creation */ try { - await mailchimp.campaigns.setContent(newCampaign.id, { html: htmlContent(link) }); + await mailchimp.campaigns.setContent(newCampaign.id, { html: htmlContent(link, title) }); } catch (error) { return core.setFailed(`Failed adding content to campaign: ${ JSON.stringify(error) }`); } From 1e3ec47ff4019a3d10a1c09fe4db2922227cef4a Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Tue, 6 Dec 2022 10:47:35 +0100 Subject: [PATCH 07/37] ci: update generic workflows (#879) --- .github/workflows/scripts/mailchimp/index.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/scripts/mailchimp/index.js b/.github/workflows/scripts/mailchimp/index.js index 387176b41..4a200c6c4 100644 --- a/.github/workflows/scripts/mailchimp/index.js +++ b/.github/workflows/scripts/mailchimp/index.js @@ -27,8 +27,14 @@ module.exports = async (link, title) => { type: 'regular', recipients: { list_id: '6e3e437abe', - segments_opts: { - saved_segment_id: 'tsc-voting-email' + segment_opts: { + match: 'any', + conditions: [{ + condition_type: 'Interests', + field: 'interests-2801e38b9f', + op: 'interestcontains', + value: ['f7204f9b90'] + }] } }, settings: { From 95643a73e102b0d97f4f8b5f75c5376ebac0c41c Mon Sep 17 00:00:00 2001 From: Animesh Kumar Date: Mon, 19 Dec 2022 15:52:05 +0530 Subject: [PATCH 08/37] docs: update readme, add sponsors section, review requested (#886) --- README.md | 49 ++++++++++++++++++++++++++++++++++++ assets/bump-sh-white-bg.png | Bin 0 -> 17716 bytes assets/bump-sh.svg | 19 ++++++++++++++ assets/ibm.png | Bin 0 -> 2125 bytes assets/postman.png | Bin 0 -> 28530 bytes assets/redhat.png | Bin 0 -> 3406 bytes 6 files changed, 68 insertions(+) create mode 100644 assets/bump-sh-white-bg.png create mode 100644 assets/bump-sh.svg create mode 100644 assets/ibm.png create mode 100644 assets/postman.png create mode 100644 assets/redhat.png diff --git a/README.md b/README.md index c3079baa5..d37f26308 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@
+ ## Read the specification @@ -85,6 +87,53 @@ Definition of the Gemini Websocket API. Check out the [examples](https://github.com/asyncapi/asyncapi/blob/master/examples) directory for more examples. +## Our Sponsors + +### Platinum + +

+ + + Solace logo + +      + + IBM logo + +      + + IQVIA logo + +      + + Postman logo + +

+ + +### Gold + +

+ + + RedHat logo + +      + +

+ +### Silver + +

+ + + Bump.sh logo + +      + +

+ + ## Contributors Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): diff --git a/assets/bump-sh-white-bg.png b/assets/bump-sh-white-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..8e8414a781954dd0f97861199cedb4d93f751e6a GIT binary patch literal 17716 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 + + + + + + + + + + + + + + + + + + diff --git a/assets/ibm.png b/assets/ibm.png new file mode 100644 index 0000000000000000000000000000000000000000..9a7775d282e7562264fbd21997c1fdc01c8412ea GIT binary patch literal 2125 zcmV-T2(tHyP)i}uKs=?w7Yrmhl-$;YVhN;-vn{(B1Fq@c3Mh&EM$s0A9NQU%Mo8!ub3B09d&ITe{8L?zYP2n6=%0q}Drq#%`L? zuf^nYozhW>%0`07;q3F8000M&NklTVtxc5^Pfe+5G+HhF2p}f@H^AU@=BOx zy8=&f>mhz!q%}o;1%x!+bei|$5%w;Pe#vh z>}~Om&$f?>b~wHg^3(najtw3bf$gKBHIA=0v%efTcP!^v#UpNg=IwFpc@cki?O1qN z$KTeEidH$kcC@U2m9uv2@fp&w{cY^TvG~s%ds5UsK$q4xnVjMje>8DCbb!blhc4m) zY@@oj<+rVUK%C=m`yPh49teUU2!bF8q9+Vo;5eLNpN)HcvLog@;4?d$PZ#k}edZI& zmravUyB}Ebtl>qqD<_mgoN^ZIb3!TM1$I1_%}%wojy;~ck()X8eE4bMS!d^eX|Ln_ z-Ph2uROO{_EE=TTZnW2New?VGV|WgL^_c&i7CX+36E$?~`7z))Z1|{XvttoCb1cVC zd{ngAvBw|j`lgNxFDWICO&=8=3!4-9nd6OvcvynRIMGrz47E|u0pL;7^JH%hSZ0nd zF5+Q1-@BbI8%A1wsT9wehJJff|BVm?K@bE%5CoBu%pg#UVDb#?!@*~A1!${lTA}7s zFE$Q>wX@%GH9KHBdp#dexKAkK#a5p{)3mj^X`*RbWnB$&@(p9`^y`CuSwO2x0&J8A zA5b_BJJ#g9xVmX#oGuGK$}wW&3>SJjb88&uvYQpm9Y^2g7-Qpsybd}BQj+G5Jzjp8 z4vn+(-E$lPDJ=`fK`HsRGEatg&oQ(r$-;5CEQUCkkNJ1du`=sx<=FF!4~wmNgzh=! zzzRki$FeYCXl4-s?|2ib*_gi{`#`ug>=-(eNcuq2WDPY{1f1j}Ou2c44fYOP9j9uJ zCQIdSEWmK!6rC7qI-LTe$t;1JD$XYVu$bEfFt$Sw1VIo4K@bERj3BhDfXc*RI9ny3Uo5j7`*c`E1_{$I(RJsn+qE^06B1p+^Plh2scS zXiDc;eOBR7{iu)!xL{#N9EU^Hd?%e_s3_hs1IPI7YaaIc;#hF)d>o|XGqy6^W3QIJIM$ZaMLWiBCzkDI z=*ICLnmlFke*BENSUcUfNCHhL+hn6DKC-{ZVww?jIq11q@z;l%FXQh#Fq}2O^2cAm zi^y)by=ix_9pf371VIo4K@bE%u+?;~W@=nLUHqkXgx?k(2v{!|CzHy2O z3J13@@Am(x*;I1;4i>;l7vbdSn`7JBV z7G&8mGzXyk$I>^)wlz)5j-i9g+Ir^Lx;AfR53FzX9Dr@r1i8^`5LeKf5* zs#lJ4<7{pmms8HXHm%nu$0Aqe&5h$yre1ip2ldHuewQ#uj*I%TWj1|vEb?POjvO^mSE@)>-(h=*a9pCEPF7&flIMcH|sJ4jJ-a%6moY~X<0$W81bo?)NY zU#(%cv0_Ll$;F8kgKCNKCDz9w2!bF8f*^>VGI2mQ4R|ng5f5TpH>dIZ&n(DEUHu}y zUBO9ROlNU2J!K}E6XwR6dnV(*yN?#dAHC%D6ZS3=M=wNxT1|6}d2V-W@XtXXE^)baH#1^Vd=IR1TIaS_$KzC+2t_m29)k8T}* z)sFeUj^l9n%eIR5`!Al;@;Dx$iWRtZoPZ0!%pLy^=4xtrI_g|!00000NkvXXu0mjf D%#|ko literal 0 HcmV?d00001 diff --git a/assets/postman.png b/assets/postman.png new file mode 100644 index 0000000000000000000000000000000000000000..b3715fdd68bd0f40a10174d8d44bfa1e3a1726a1 GIT binary patch literal 28530 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 GF8>eJ*^~wV literal 0 HcmV?d00001 diff --git a/assets/redhat.png b/assets/redhat.png new file mode 100644 index 0000000000000000000000000000000000000000..6cc1af0f94006c48bdd6acda470786aad1dda28d GIT binary patch literal 3406 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 literal 0 HcmV?d00001 From 6c252c2a34408e300705859feb2e325247e2572c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Urba=C5=84czyk?= Date: Tue, 20 Dec 2022 09:18:36 +0100 Subject: [PATCH 09/37] docs: fix websocket-gemini message's payload example (#884) --- examples/websocket-gemini.yml | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/examples/websocket-gemini.yml b/examples/websocket-gemini.yml index 75af8d4d6..06e632017 100644 --- a/examples/websocket-gemini.yml +++ b/examples/websocket-gemini.yml @@ -122,9 +122,9 @@ components: events: - type: change side: bid - price: '54350.40' - remaining: '0.002' - delta: '0.002' + price: 54350.40 + remaining: 0.002 + delta: 0.002 reason: place - name: heartbeatMessage summary: Example of additional heartbeat message when you enable them. @@ -158,12 +158,10 @@ components: events: $ref: '#/components/schemas/events' timestamp: - type: string - format: date-time + type: number description: The timestamp in seconds for this group of events (included for compatibility reasons). We recommend using the timestampms field instead. timestampms: - type: string - format: time + type: number description: The timestamp in milliseconds for this group of events. required: - type @@ -194,7 +192,7 @@ components: enum: ['trade', 'change', 'auction, block_trade'] price: type: number - multipleOf: 1.000 + multipleOf: 0.01 description: The price of this order book entry. side: type: string @@ -205,9 +203,7 @@ components: description: Indicates why the change has occurred. initial is for the initial response message, which will show the entire existing state of the order book. remaining: type: number - multipleOf: 1.000 description: The quantity remaining at that price level after this change occurred. May be zero if all orders at this price level have been filled or canceled. delta: type: number - multipleOf: 1.000 description: The quantity changed. May be negative, if an order is filled or canceled. For initial messages, delta will equal remaining. \ No newline at end of file From 143ddd0638cf1284f35fc915ddc170bcdf0a5a35 Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Mon, 30 Jan 2023 17:24:48 +0100 Subject: [PATCH 10/37] ci: update generic workflows (#897) --- .../workflows/add-good-first-issue-labels.yml | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/.github/workflows/add-good-first-issue-labels.yml b/.github/workflows/add-good-first-issue-labels.yml index 202345269..e70a70017 100644 --- a/.github/workflows/add-good-first-issue-labels.yml +++ b/.github/workflows/add-good-first-issue-labels.yml @@ -4,36 +4,37 @@ # Purpose of this workflow is to enable anyone to label issue with 'Good First Issue' and 'area/*' with a single command. name: Add 'Good First Issue' and 'area/*' labels # if proper comment added -on: - issue_comment: - types: - - created +on: + issue_comment: + types: + - created jobs: add-labels: - if: ${{!github.event.issue.pull_request && github.event.issue.state != 'closed' && github.actor != 'asyncapi-bot'}} + if: ${{(!github.event.issue.pull_request && github.event.issue.state != 'closed' && github.actor != 'asyncapi-bot') && (contains(github.event.comment.body, '/good-first-issue') || contains(github.event.comment.body, '/gfi' ))}} runs-on: ubuntu-latest steps: - name: Add label - if: contains(github.event.comment.body, '/good-first-issue') || contains(github.event.comment.body, '/gfi' ) uses: actions/github-script@v5 with: github-token: ${{ secrets.GH_TOKEN }} script: | const areas = ['javascript', 'typescript', 'java' , 'go', 'docs', 'ci-cd', 'design']; - const values = context.payload.comment.body.trim().split(" "); - switch(values[1]){ + const words = context.payload.comment.body.trim().split(" "); + const areaIndex = words.findIndex((word)=> word === '/gfi' || word === '/good-first-issue') + 1 + let area = words[areaIndex]; + switch(area){ case 'ts': - values[1] = 'typescript'; + area = 'typescript'; break; case 'js': - values[1] = 'javascript'; + area = 'javascript'; break; case 'markdown': - values[1] = 'docs'; + area = 'docs'; break; } - if(values.length != 2 || !areas.includes(values[1])){ + if(!areas.includes(area)){ const message = `Hey @${context.payload.sender.login}, your message doesn't follow the requirements, you can try \`/help\`.` await github.rest.issues.createComment({ @@ -44,14 +45,14 @@ jobs: }) } else { - //remove complexity and areas if there are any before adding new labels; + // remove area if there is any before adding new labels. const currentLabels = (await github.rest.issues.listLabelsOnIssue({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, })).data.map(label => label.name); - const shouldBeRemoved = currentLabels.filter(label => (label.startsWith('area/') && !label.endsWith(values[1]))); + const shouldBeRemoved = currentLabels.filter(label => (label.startsWith('area/') && !label.endsWith(area)); shouldBeRemoved.forEach(label => { github.rest.issues.deleteLabel({ owner: context.repo.owner, @@ -60,11 +61,11 @@ jobs: }); }); - //add new labels + // Add new labels. github.rest.issues.addLabels({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - labels: ['good first issue', `area/${values[1]}`] + labels: ['good first issue', `area/${area}`] }); } From 8087feec522e2685172c0ccd729a4d2abc7f1360 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Jan 2023 17:53:01 +0100 Subject: [PATCH 11/37] chore(deps): bump cookiejar from 2.1.3 to 2.1.4 in /.github/workflows/scripts/mailchimp (#898) --- .../workflows/scripts/mailchimp/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/scripts/mailchimp/package-lock.json b/.github/workflows/scripts/mailchimp/package-lock.json index e7f570381..089364fa8 100644 --- a/.github/workflows/scripts/mailchimp/package-lock.json +++ b/.github/workflows/scripts/mailchimp/package-lock.json @@ -74,9 +74,9 @@ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "node_modules/cookiejar": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", - "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==" + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" }, "node_modules/core-util-is": { "version": "1.0.3", @@ -397,9 +397,9 @@ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "cookiejar": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", - "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==" + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" }, "core-util-is": { "version": "1.0.3", From 1824379ba6252bfb52550337a86ca9b10a33b3aa Mon Sep 17 00:00:00 2001 From: Ace <40604284+AceTheCreator@users.noreply.github.com> Date: Wed, 1 Feb 2023 17:00:43 +0100 Subject: [PATCH 12/37] feat: release for version 2.6.0 of the spec (#902) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sergio Moya <1083296+smoya@users.noreply.github.com> Co-authored-by: Alex Wichmann Co-authored-by: asyncapi-bot-eve Co-authored-by: Jeremy Whitlock Co-authored-by: Lukasz Gornicki Co-authored-by: derberg Co-authored-by: Maciej Urbańczyk Co-authored-by: Vladimír Gorej --- 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/social-media/backend/asyncapi.yaml | 2 +- examples/social-media/comments-service/asyncapi.yaml | 2 +- examples/social-media/frontend/asyncapi.yaml | 2 +- .../social-media/notification-service/asyncapi.yaml | 2 +- examples/social-media/public-api/asyncapi.yaml | 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 | 12 ++++++++---- 23 files changed, 31 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index d37f26308..c198d686e 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,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. 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.6.0](https://github.com/asyncapi/spec/blob/v2.6.0/spec/asyncapi.md) (latest) +- [Version 2.5.0](https://github.com/asyncapi/spec/blob/v2.5.0/spec/asyncapi.md) - [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) diff --git a/examples/anyof.yml b/examples/anyof.yml index a73ac4090..3feb5760e 100644 --- a/examples/anyof.yml +++ b/examples/anyof.yml @@ -1,4 +1,4 @@ -asyncapi: '2.5.0' +asyncapi: '2.6.0' info: title: AnyOf example version: '1.0.0' diff --git a/examples/application-headers.yml b/examples/application-headers.yml index 0ebe339d1..ad361ae3f 100644 --- a/examples/application-headers.yml +++ b/examples/application-headers.yml @@ -1,4 +1,4 @@ -asyncapi: '2.5.0' +asyncapi: '2.6.0' info: title: Application Headers example version: '1.0.0' diff --git a/examples/correlation-id.yml b/examples/correlation-id.yml index 33bb2770e..cb2a50ab1 100644 --- a/examples/correlation-id.yml +++ b/examples/correlation-id.yml @@ -1,4 +1,4 @@ -asyncapi: '2.5.0' +asyncapi: '2.6.0' info: title: Correlation ID Example version: '1.0.0' diff --git a/examples/gitter-streaming.yml b/examples/gitter-streaming.yml index 1d53a01bb..444bc9b81 100644 --- a/examples/gitter-streaming.yml +++ b/examples/gitter-streaming.yml @@ -1,4 +1,4 @@ -asyncapi: '2.5.0' +asyncapi: '2.6.0' id: 'tag:stream.gitter.im,2022:api' info: title: Gitter Streaming API diff --git a/examples/mercure.yml b/examples/mercure.yml index 388f4dbc1..fc089876c 100644 --- a/examples/mercure.yml +++ b/examples/mercure.yml @@ -1,4 +1,4 @@ -asyncapi: '2.5.0' +asyncapi: '2.6.0' info: title: Mercure Hub Example version: '1.0.0' diff --git a/examples/not.yml b/examples/not.yml index 0b4e2e716..6248ebf06 100644 --- a/examples/not.yml +++ b/examples/not.yml @@ -1,4 +1,4 @@ -asyncapi: '2.5.0' +asyncapi: '2.6.0' info: title: Not example version: '1.0.0' diff --git a/examples/oneof.yml b/examples/oneof.yml index 6bc4c92e3..034944537 100644 --- a/examples/oneof.yml +++ b/examples/oneof.yml @@ -1,4 +1,4 @@ -asyncapi: '2.5.0' +asyncapi: '2.6.0' info: title: OneOf example version: '1.0.0' diff --git a/examples/operation-security.yml b/examples/operation-security.yml index b0d234bf4..3bcffba5b 100644 --- a/examples/operation-security.yml +++ b/examples/operation-security.yml @@ -1,4 +1,4 @@ -asyncapi: 2.5.0 +asyncapi: 2.6.0 info: title: Notifications version: 1.0.0 diff --git a/examples/rpc-client.yml b/examples/rpc-client.yml index 68f5d8014..cf86c6510 100644 --- a/examples/rpc-client.yml +++ b/examples/rpc-client.yml @@ -1,4 +1,4 @@ -asyncapi: '2.5.0' +asyncapi: '2.6.0' id: 'urn:example:rpcclient' defaultContentType: application/json diff --git a/examples/rpc-server.yml b/examples/rpc-server.yml index de4896eb6..61cf6c5aa 100644 --- a/examples/rpc-server.yml +++ b/examples/rpc-server.yml @@ -1,4 +1,4 @@ -asyncapi: '2.5.0' +asyncapi: '2.6.0' id: 'urn:example:rpcserver' defaultContentType: application/json diff --git a/examples/simple.yml b/examples/simple.yml index 329d5073b..6c9aaec66 100644 --- a/examples/simple.yml +++ b/examples/simple.yml @@ -1,4 +1,4 @@ -asyncapi: '2.5.0' +asyncapi: '2.6.0' info: title: Account Service version: 1.0.0 diff --git a/examples/slack-rtm.yml b/examples/slack-rtm.yml index 20234a2bb..a2408f2c3 100644 --- a/examples/slack-rtm.yml +++ b/examples/slack-rtm.yml @@ -1,4 +1,4 @@ -asyncapi: '2.5.0' +asyncapi: '2.6.0' id: 'wss://wss-primary.slack.com/websocket' info: title: Slack Real Time Messaging API diff --git a/examples/social-media/backend/asyncapi.yaml b/examples/social-media/backend/asyncapi.yaml index b2f6a9a31..9345b5e63 100644 --- a/examples/social-media/backend/asyncapi.yaml +++ b/examples/social-media/backend/asyncapi.yaml @@ -1,4 +1,4 @@ -asyncapi: 2.5.0 +asyncapi: 2.6.0 info: title: Website Backend diff --git a/examples/social-media/comments-service/asyncapi.yaml b/examples/social-media/comments-service/asyncapi.yaml index 308c10b03..d60c620d1 100644 --- a/examples/social-media/comments-service/asyncapi.yaml +++ b/examples/social-media/comments-service/asyncapi.yaml @@ -1,4 +1,4 @@ -asyncapi: 2.5.0 +asyncapi: 2.6.0 info: title: Comments Service diff --git a/examples/social-media/frontend/asyncapi.yaml b/examples/social-media/frontend/asyncapi.yaml index 1f46ede41..9d06d52ec 100644 --- a/examples/social-media/frontend/asyncapi.yaml +++ b/examples/social-media/frontend/asyncapi.yaml @@ -1,4 +1,4 @@ -asyncapi: 2.5.0 +asyncapi: 2.6.0 info: title: Website WebSocket Client diff --git a/examples/social-media/notification-service/asyncapi.yaml b/examples/social-media/notification-service/asyncapi.yaml index 0789a7b6b..7f1fd80b4 100644 --- a/examples/social-media/notification-service/asyncapi.yaml +++ b/examples/social-media/notification-service/asyncapi.yaml @@ -1,4 +1,4 @@ -asyncapi: 2.5.0 +asyncapi: 2.6.0 info: title: Notifications Service diff --git a/examples/social-media/public-api/asyncapi.yaml b/examples/social-media/public-api/asyncapi.yaml index f97ee0b78..fa1c23412 100644 --- a/examples/social-media/public-api/asyncapi.yaml +++ b/examples/social-media/public-api/asyncapi.yaml @@ -1,4 +1,4 @@ -asyncapi: 2.5.0 +asyncapi: 2.6.0 info: title: Public API diff --git a/examples/streetlights-kafka.yml b/examples/streetlights-kafka.yml index 916111154..3486e1865 100644 --- a/examples/streetlights-kafka.yml +++ b/examples/streetlights-kafka.yml @@ -1,4 +1,4 @@ -asyncapi: '2.5.0' +asyncapi: '2.6.0' info: title: Streetlights Kafka API version: '1.0.0' diff --git a/examples/streetlights-mqtt.yml b/examples/streetlights-mqtt.yml index b3721d878..24d173cd3 100644 --- a/examples/streetlights-mqtt.yml +++ b/examples/streetlights-mqtt.yml @@ -1,4 +1,4 @@ -asyncapi: '2.5.0' +asyncapi: '2.6.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 faf122763..5e443ec41 100644 --- a/examples/streetlights-operation-security.yml +++ b/examples/streetlights-operation-security.yml @@ -1,4 +1,4 @@ -asyncapi: '2.5.0' +asyncapi: '2.6.0' info: title: Streetlights Kafka API version: '1.0.0' diff --git a/examples/websocket-gemini.yml b/examples/websocket-gemini.yml index 06e632017..b799c1c56 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.5.0' +asyncapi: '2.6.0' # # Overal information for users of the application diff --git a/spec/asyncapi.md b/spec/asyncapi.md index f78e94b1c..4bd998a55 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.5.0 +#### Version 2.6.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). @@ -105,7 +105,7 @@ A message is the mechanism by which information is exchanged via a channel betwe A channel is an addressable component, made available by the [server](#definitionsServer), for the organization of [messages](#definitionsMessage). [Producer](#definitionsProducer) applications send messages to channels and [consumer](#definitionsConsumer) applications consume messages from channels. [Servers](#definitionsServer) MAY support many channel instances, allowing messages with different content to be addressed to different channels. Depending on the [server](#definitionsServer) implementation, the channel MAY be included in the message via protocol-defined headers. #### Protocol -A protocol is the mechanism (wireline protocol or API) by which [messages](#definitionsMessage) are exchanged between the application and the [channel](#definitionsChannel). Example protocols include, but are not limited to, AMQP, HTTP, JMS, Kafka, Anypoint MQ, MQTT, Solace, STOMP, Mercure, WebSocket. +A protocol is the mechanism (wireline protocol or API) by which [messages](#definitionsMessage) are exchanged between the application and the [channel](#definitionsChannel). Example protocols include, but are not limited to, AMQP, HTTP, JMS, Kafka, Anypoint MQ, MQTT, Solace, STOMP, Mercure, WebSocket, Google Pub/Sub, Pulsar. #### Bindings A "binding" (or "protocol binding") is a mechanism to define protocol-specific information. Therefore, a protocol binding MUST define protocol-specific information only. @@ -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`, `googlepubsub`. +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`, `pulsar`. 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. @@ -1009,6 +1009,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. `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. +`pulsar` | [Pulsar Server Binding](https://github.com/asyncapi/bindings/tree/master/pulsar#server-binding-object) | Protocol-specific information for a Pulsar server. This object MAY be extended with [Specification Extensions](#specificationExtensions). @@ -1040,6 +1041,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. `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. +`pulsar` | [Pulsar Channel Binding](https://github.com/asyncapi/bindings/tree/master/pulsar#channel-binding-object) | Protocol-specific information for a Pulsar channel. This object MAY be extended with [Specification Extensions](#specificationExtensions). @@ -1071,6 +1073,7 @@ Field Name | Type | Description `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. +`pulsar` | [Pulsar Operation Binding](https://github.com/asyncapi/bindings/tree/master/pulsar#operation-binding-fields) | Protocol-specific information for a Pulsar operation. This object MAY be extended with [Specification Extensions](#specificationExtensions). @@ -1103,6 +1106,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. `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. +`pulsar` | [Pulsar Message Binding](https://github.com/asyncapi/bindings/tree/master/pulsar#message-binding-fields) | Protocol-specific information for a Pulsar message. This object MAY be extended with [Specification Extensions](#specificationExtensions). @@ -1144,7 +1148,7 @@ The following table contains a set of values that every implementation MUST supp Name | Allowed values | Notes ---|:---:|--- -[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. +[AsyncAPI 2.6.0 Schema Object](#schemaObject) | `application/vnd.aai.asyncapi;version=2.6.0`, `application/vnd.aai.asyncapi+json;version=2.6.0`, `application/vnd.aai.asyncapi+yaml;version=2.6.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 2e301c931a92ae6a27a61bb8dbc43aa765e10c69 Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Mon, 13 Feb 2023 20:20:53 +0100 Subject: [PATCH 13/37] ci: update generic workflows (#906) --- .github/workflows/add-good-first-issue-labels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/add-good-first-issue-labels.yml b/.github/workflows/add-good-first-issue-labels.yml index e70a70017..06e470d86 100644 --- a/.github/workflows/add-good-first-issue-labels.yml +++ b/.github/workflows/add-good-first-issue-labels.yml @@ -52,7 +52,7 @@ jobs: repo: context.repo.repo, })).data.map(label => label.name); - const shouldBeRemoved = currentLabels.filter(label => (label.startsWith('area/') && !label.endsWith(area)); + const shouldBeRemoved = currentLabels.filter(label => (label.startsWith('area/') && !label.endsWith(area))); shouldBeRemoved.forEach(label => { github.rest.issues.deleteLabel({ owner: context.repo.owner, From 7a6aba681e24d75dd485f9a0bcb13ba6d860219c Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Tue, 14 Mar 2023 10:12:07 +0100 Subject: [PATCH 14/37] ci: update generic workflows (#911) --- .github/workflows/welcome-first-time-contrib.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/welcome-first-time-contrib.yml b/.github/workflows/welcome-first-time-contrib.yml index e72fecef8..1eab8fd72 100644 --- a/.github/workflows/welcome-first-time-contrib.yml +++ b/.github/workflows/welcome-first-time-contrib.yml @@ -21,7 +21,7 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const issueMessage = `Welcome to AsyncAPI. Thanks a lot for reporting your first issue. Please check out our [contributors guide](https://github.com/asyncapi/community/blob/master/CONTRIBUTING.md) and the instructions about a [basic recommended setup](https://github.com/asyncapi/.github/blob/master/git-workflow.md) useful for opening a pull request.
Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out [this issue](https://github.com/asyncapi/asyncapi/issues/115).`; + const issueMessage = `Welcome to AsyncAPI. Thanks a lot for reporting your first issue. Please check out our [contributors guide](https://github.com/asyncapi/community/blob/master/CONTRIBUTING.md) and the instructions about a [basic recommended setup](https://github.com/asyncapi/community/blob/master/git-workflow.md) useful for opening a pull request.
Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out [this issue](https://github.com/asyncapi/asyncapi/issues/115).`; const prMessage = `Welcome to AsyncAPI. Thanks a lot for creating your first pull request. Please check out our [contributors guide](https://github.com/asyncapi/community/blob/master/CONTRIBUTING.md) useful for opening a pull request.
Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out [this issue](https://github.com/asyncapi/asyncapi/issues/115).`; if (!issueMessage && !prMessage) { throw new Error('Action must have at least one of issue-message or pr-message set'); From 19157537b3c42382620760919f237d2eb10b1b35 Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Tue, 28 Mar 2023 09:36:30 +0200 Subject: [PATCH 15/37] ci: update generic workflows (#916) --- .github/workflows/link-check-cron.yml | 37 --------------------------- .github/workflows/link-check-pr.yml | 28 -------------------- 2 files changed, 65 deletions(-) delete mode 100644 .github/workflows/link-check-cron.yml delete mode 100644 .github/workflows/link-check-pr.yml diff --git a/.github/workflows/link-check-cron.yml b/.github/workflows/link-check-cron.yml deleted file mode 100644 index 873d4297f..000000000 --- a/.github/workflows/link-check-cron.yml +++ /dev/null @@ -1,37 +0,0 @@ -# This workflow is centrally managed in https://github.com/asyncapi/.github/ -# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo - -name: Check Markdown links (Weekly) - -on: - workflow_dispatch: - schedule: - # At 00:00 UTC on every Monday - - cron: '0 0 * * 0' - -jobs: - External-link-validation-weekly: - if: startsWith(github.repository, 'asyncapi/') - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - # Checks the status of hyperlinks in .md files - - name: Check links - uses: gaurav-nelson/github-action-markdown-link-check@0a51127e9955b855a9bbfa1ff5577f1d1338c9a5 #1.0.14 but pointing to commit for security reasons - with: - use-quiet-mode: 'yes' - use-verbose-mode: 'yes' - - # A configuration file can be included, indicating the properties of the link check action - # More information can be found here: https://github.com/tcort/markdown-link-check#config-file-format - # Create mlc_config.json file in the root of the directory - - - name: Report workflow run status to Slack - uses: 8398a7/action-slack@v3 - with: - status: ${{ job.status }} - fields: repo,action,workflow - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CI_FAIL_NOTIFY }} - if: failure() # Only, on failure, send a message on the 94_bot-failing-ci slack channel diff --git a/.github/workflows/link-check-pr.yml b/.github/workflows/link-check-pr.yml deleted file mode 100644 index 51f6cf780..000000000 --- a/.github/workflows/link-check-pr.yml +++ /dev/null @@ -1,28 +0,0 @@ -# This workflow is centrally managed in https://github.com/asyncapi/.github/ -# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo - -name: Check Markdown links - -on: - pull_request_target: - types: [synchronize, ready_for_review, opened, reopened] - paths: - - '**.md' - -jobs: - External-link-validation-on-PR: - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@v3 - - name: Check links - uses: gaurav-nelson/github-action-markdown-link-check@0a51127e9955b855a9bbfa1ff5577f1d1338c9a5 #1.0.14 but pointing to commit for security reasons - with: - use-quiet-mode: 'yes' - use-verbose-mode: 'yes' - check-modified-files-only: 'yes' # Only modified files are checked on PRs - - - # A configuration file can be included, indicating the properties of the link check action - # More information can be found here: https://github.com/tcort/markdown-link-check#config-file-format - # Create mlc_config.json file in the root of the directory From be29f8fab6db3751a0f12642d0cb94fd8b23171b Mon Sep 17 00:00:00 2001 From: Sambhav Gupta <81870866+sambhavgupta0705@users.noreply.github.com> Date: Mon, 3 Apr 2023 13:52:19 +0530 Subject: [PATCH 16/37] docs: remove `are` from polymorphism section (#909) Co-authored-by: Lukasz Gornicki --- spec/asyncapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/asyncapi.md b/spec/asyncapi.md index 4bd998a55..1fb6c8bd4 100644 --- a/spec/asyncapi.md +++ b/spec/asyncapi.md @@ -1822,7 +1822,7 @@ While composition offers model extensibility, it does not imply a hierarchy betw To support polymorphism, AsyncAPI Specification adds the support of the `discriminator` field. When used, the `discriminator` will be the name of the property used to decide which schema definition is used to validate the structure of the model. As such, the `discriminator` field MUST be a required field. -There are are two ways to define the value of a discriminator for an inheriting instance. +There are two ways to define the value of a discriminator for an inheriting instance. - Use the schema's name. - Override the schema's name by overriding the property with a new value. If exists, this takes precedence over the schema's name. From e5520f335c5e392014c235ccb2dd3045739b069e Mon Sep 17 00:00:00 2001 From: Lukasz Gornicki Date: Tue, 4 Apr 2023 18:35:16 +0200 Subject: [PATCH 17/37] ci: fix spec update in website workflow (#921) --- .github/workflows/update-spec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-spec.yaml b/.github/workflows/update-spec.yaml index 528a66e5c..d5ad7aa1e 100644 --- a/.github/workflows/update-spec.yaml +++ b/.github/workflows/update-spec.yaml @@ -30,7 +30,7 @@ jobs: git config --global user.email info@asyncapi.io - name: Get latest release id: latest_version - uses: abatilo/release-info-action@v1.3.0 + uses: abatilo/release-info-action@5774bec4e3eabad433b4ae8f625e83afa0e7bb22 # 1.3.2 release https://github.com/abatilo/release-info-action/releases/tag/v1.3.2 with: owner: asyncapi repo: spec From b61efe0aafbd515b11dcda3aa4e6e654a161ae8a Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Tue, 4 Apr 2023 20:42:11 +0200 Subject: [PATCH 18/37] ci: update generic workflows (#922) --- .github/workflows/lint-pr-title.yml | 4 ++-- .github/workflows/sentiment-analysis.yml | 2 +- .github/workflows/welcome-first-time-contrib.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/lint-pr-title.yml b/.github/workflows/lint-pr-title.yml index c4a942a91..b3015a451 100644 --- a/.github/workflows/lint-pr-title.yml +++ b/.github/workflows/lint-pr-title.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: # Since this workflow is REQUIRED for a PR to be mergable, we have to have this 'if' statement in step level instead of job level. - - if: ${{ !contains(fromJson('["asyncapi-bot", "dependabot[bot]", "dependabot-preview[bot]", "allcontributors"]'), github.actor) }} + - if: ${{ !contains(fromJson('["asyncapi-bot", "dependabot[bot]", "dependabot-preview[bot]", "allcontributors[bot]"]'), github.actor) }} uses: amannn/action-semantic-pull-request@505e44b4f33b4c801f063838b3f053990ee46ea7 #version 4.6.0 id: lint_pr_title env: @@ -24,7 +24,7 @@ jobs: The subject "{subject}" found in the pull request title "{title}" should start with a lowercase character. # Comments the error message from the above lint_pr_title action - - if: ${{ always() && steps.lint_pr_title.outputs.error_message != null && !contains(fromJson('["asyncapi-bot", "dependabot[bot]", "dependabot-preview[bot]", "allcontributors"]'), github.actor)}} + - if: ${{ always() && steps.lint_pr_title.outputs.error_message != null && !contains(fromJson('["asyncapi-bot", "dependabot[bot]", "dependabot-preview[bot]", "allcontributors[bot]"]'), github.actor)}} name: Comment on PR uses: marocchino/sticky-pull-request-comment@39c5b5dc7717447d0cba270cd115037d32d28443 #version 2.2 with: diff --git a/.github/workflows/sentiment-analysis.yml b/.github/workflows/sentiment-analysis.yml index cd8ab05f7..f1f845a0d 100644 --- a/.github/workflows/sentiment-analysis.yml +++ b/.github/workflows/sentiment-analysis.yml @@ -26,7 +26,7 @@ on: - edited jobs: sentiments: - if: ${{ !contains(fromJson('["asyncapi-bot", "dependabot[bot]", "dependabot-preview[bot]", "allcontributors"]'), github.actor) }} + if: ${{ !contains(fromJson('["asyncapi-bot", "dependabot[bot]", "dependabot-preview[bot]", "allcontributors[bot]"]'), github.actor) }} name: Checking sentiments runs-on: ubuntu-latest steps: diff --git a/.github/workflows/welcome-first-time-contrib.yml b/.github/workflows/welcome-first-time-contrib.yml index 1eab8fd72..34fb25d20 100644 --- a/.github/workflows/welcome-first-time-contrib.yml +++ b/.github/workflows/welcome-first-time-contrib.yml @@ -14,7 +14,7 @@ on: jobs: welcome: name: Post welcome message - if: ${{ !contains(fromJson('["asyncapi-bot", "dependabot[bot]", "dependabot-preview[bot]", "allcontributors"]'), github.actor) }} + if: ${{ !contains(fromJson('["asyncapi-bot", "dependabot[bot]", "dependabot-preview[bot]", "allcontributors[bot]"]'), github.actor) }} runs-on: ubuntu-latest steps: - uses: actions/github-script@v3 From 806a8a6f3f30042cfe88ef4860d8b2ef42d55bcd Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Thu, 13 Apr 2023 09:07:33 +0200 Subject: [PATCH 19/37] ci: update generic workflows (#924) --- .../workflows/add-good-first-issue-labels.yml | 2 +- ...d-ready-to-merge-or-do-not-merge-label.yml | 6 +- .../automerge-for-humans-merging.yml | 2 +- ...ns-remove-ready-to-merge-label-on-edit.yml | 2 +- .github/workflows/automerge-orphans.yml | 8 +- .github/workflows/automerge.yml | 6 +- .github/workflows/help-command.yml | 60 +++++--- .../workflows/issues-prs-notifications.yml | 18 ++- .github/workflows/lint-pr-title.yml | 6 +- .../workflows/notify-tsc-members-mention.yml | 132 +++++++++--------- .github/workflows/release-announcements.yml | 16 ++- .github/workflows/sentiment-analysis.yml | 45 ------ .../workflows/welcome-first-time-contrib.yml | 6 +- 13 files changed, 145 insertions(+), 164 deletions(-) delete mode 100644 .github/workflows/sentiment-analysis.yml diff --git a/.github/workflows/add-good-first-issue-labels.yml b/.github/workflows/add-good-first-issue-labels.yml index 06e470d86..2ae3a056a 100644 --- a/.github/workflows/add-good-first-issue-labels.yml +++ b/.github/workflows/add-good-first-issue-labels.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Add label - uses: actions/github-script@v5 + uses: actions/github-script@v6 with: github-token: ${{ secrets.GH_TOKEN }} script: | diff --git a/.github/workflows/automerge-for-humans-add-ready-to-merge-or-do-not-merge-label.yml b/.github/workflows/automerge-for-humans-add-ready-to-merge-or-do-not-merge-label.yml index 79c8079ec..66606fc17 100644 --- a/.github/workflows/automerge-for-humans-add-ready-to-merge-or-do-not-merge-label.yml +++ b/.github/workflows/automerge-for-humans-add-ready-to-merge-or-do-not-merge-label.yml @@ -26,7 +26,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Add ready-to-merge label - uses: actions/github-script@v5 + uses: actions/github-script@v6 with: github-token: ${{ secrets.GH_TOKEN }} script: | @@ -76,7 +76,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Add do-not-merge label - uses: actions/github-script@v5 + uses: actions/github-script@v6 with: github-token: ${{ secrets.GH_TOKEN }} script: | @@ -98,7 +98,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Add autoupdate label - uses: actions/github-script@v5 + uses: actions/github-script@v6 with: github-token: ${{ secrets.GH_TOKEN }} script: | diff --git a/.github/workflows/automerge-for-humans-merging.yml b/.github/workflows/automerge-for-humans-merging.yml index 4bce61da2..9ba0be90b 100644 --- a/.github/workflows/automerge-for-humans-merging.yml +++ b/.github/workflows/automerge-for-humans-merging.yml @@ -43,7 +43,7 @@ jobs: | join("\n")' multiline: true - name: Automerge PR - uses: pascalgn/automerge-action@v0.14.3 + uses: pascalgn/automerge-action@22948e0bc22f0aa673800da838595a3e7347e584 #v0.15.6 https://github.com/pascalgn/automerge-action/releases/tag/v0.15.6 env: GITHUB_TOKEN: "${{ secrets.GH_TOKEN }}" MERGE_LABELS: "!do-not-merge,ready-to-merge" diff --git a/.github/workflows/automerge-for-humans-remove-ready-to-merge-label-on-edit.yml b/.github/workflows/automerge-for-humans-remove-ready-to-merge-label-on-edit.yml index b8fc9904d..00e7f9935 100644 --- a/.github/workflows/automerge-for-humans-remove-ready-to-merge-label-on-edit.yml +++ b/.github/workflows/automerge-for-humans-remove-ready-to-merge-label-on-edit.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Remove label - uses: actions/github-script@v5 + uses: actions/github-script@v6 with: github-token: ${{ secrets.GH_TOKEN }} script: | diff --git a/.github/workflows/automerge-orphans.yml b/.github/workflows/automerge-orphans.yml index 20322ecb7..a17768535 100644 --- a/.github/workflows/automerge-orphans.yml +++ b/.github/workflows/automerge-orphans.yml @@ -13,8 +13,10 @@ jobs: name: Find orphans and notify runs-on: ubuntu-latest steps: + - name: Checkout repository + uses: actions/checkout@v3 - name: Get list of orphans - uses: actions/github-script@v3 + uses: actions/github-script@v6 id: orphans with: github-token: ${{ secrets.GITHUB_TOKEN }} @@ -50,10 +52,10 @@ jobs: } - if: steps.orphans.outputs.found == 'true' name: Convert markdown to slack markdown - uses: LoveToKnow/slackify-markdown-action@v1.0.0 + uses: asyncapi/.github/.github/actions/slackify-markdown@master id: issuemarkdown with: - text: "-> [${{steps.orphans.outputs.title}}](${{steps.orphans.outputs.url}})" + markdown: "-> [${{steps.orphans.outputs.title}}](${{steps.orphans.outputs.url}})" - if: steps.orphans.outputs.found == 'true' name: Send info about orphan to slack uses: rtCamp/action-slack-notify@v2 diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index 052a19c32..6dab60945 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -19,12 +19,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Autoapproving - uses: hmarr/auto-approve-action@v2 + uses: hmarr/auto-approve-action@44888193675f29a83e04faf4002fa8c0b537b1e4 # v3.2.1 is used https://github.com/hmarr/auto-approve-action/releases/tag/v3.2.1 with: github-token: "${{ secrets.GH_TOKEN_BOT_EVE }}" - name: Label autoapproved - uses: actions/github-script@v5 + uses: actions/github-script@v6 with: github-token: ${{ secrets.GH_TOKEN }} script: | @@ -41,7 +41,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Automerging - uses: pascalgn/automerge-action@v0.13.0 + uses: pascalgn/automerge-action@22948e0bc22f0aa673800da838595a3e7347e584 #v0.15.6 https://github.com/pascalgn/automerge-action/releases/tag/v0.15.6 env: GITHUB_TOKEN: "${{ secrets.GH_TOKEN }}" GITHUB_LOGIN: asyncapi-bot diff --git a/.github/workflows/help-command.yml b/.github/workflows/help-command.yml index 03f891eba..f4955c221 100644 --- a/.github/workflows/help-command.yml +++ b/.github/workflows/help-command.yml @@ -13,32 +13,48 @@ jobs: if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/help') && github.actor != 'asyncapi-bot' }} runs-on: ubuntu-latest steps: - - uses: actions-ecosystem/action-create-comment@v1 + - name: Add comment to PR + uses: actions/github-script@v6 with: - github_token: ${{ secrets.GH_TOKEN }} - body: | - Hello, @${{ github.actor }}! 👋🏼 + github-token: ${{ secrets.GH_TOKEN }} + script: | + //Yes to add comment to PR the same endpoint is use that we use to create a comment in issue + //For more details http://developer.github.com/v3/issues/comments/ + //Also proved by this action https://github.com/actions-ecosystem/action-create-comment/blob/main/src/main.ts + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `Hello, @${{ github.actor }}! 👋🏼 + + I'm Genie from the magic lamp. Looks like somebody needs a hand! 🆘 + + At the moment the following comments are supported in pull requests: + + - `/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 or it is a draft PR.` + }) - I'm Genie from the magic lamp. Looks like somebody needs a hand! 🆘 - - At the moment the following comments are supported in pull requests: - - - `/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 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 steps: - - uses: actions-ecosystem/action-create-comment@v1 + - name: Add comment to Issue + uses: actions/github-script@v6 with: - github_token: ${{ secrets.GH_TOKEN }} - body: | - Hello, @${{ github.actor }}! 👋🏼 - - I'm Genie from the magic lamp. Looks like somebody needs a hand! 🆘 - - At the moment the following comments are supported in issues: - - - `/good-first-issue {js | ts | java | go | docs | design | ci-cd} ` or `/gfi {js | ts | java | go | docs | design | ci-cd} ` - label an issue as a `good first issue`. - example: `/gfi js` or `/good-first-issue ci-cd` + github-token: ${{ secrets.GH_TOKEN }} + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `Hello, @${{ github.actor }}! 👋🏼 + + I'm Genie from the magic lamp. Looks like somebody needs a hand! 🆘 + + At the moment the following comments are supported in issues: + + - `/good-first-issue {js | ts | java | go | docs | design | ci-cd} ` or `/gfi {js | ts | java | go | docs | design | ci-cd} ` - label an issue as a `good first issue`. + example: `/gfi js` or `/good-first-issue ci-cd` + }) diff --git a/.github/workflows/issues-prs-notifications.yml b/.github/workflows/issues-prs-notifications.yml index ca665404b..78ebe9601 100644 --- a/.github/workflows/issues-prs-notifications.yml +++ b/.github/workflows/issues-prs-notifications.yml @@ -20,11 +20,13 @@ jobs: name: Notify slack on every new issue runs-on: ubuntu-latest steps: + - name: Checkout repository + uses: actions/checkout@v3 - name: Convert markdown to slack markdown for issue - uses: LoveToKnow/slackify-markdown-action@v1.0.0 + uses: asyncapi/.github/.github/actions/slackify-markdown@master id: issuemarkdown with: - text: "[${{github.event.issue.title}}](${{github.event.issue.html_url}}) \n ${{github.event.issue.body}}" + markdown: "[${{github.event.issue.title}}](${{github.event.issue.html_url}}) \n ${{github.event.issue.body}}" - name: Send info about issue uses: rtCamp/action-slack-notify@v2 env: @@ -38,11 +40,13 @@ jobs: name: Notify slack on every new pull request runs-on: ubuntu-latest steps: + - name: Checkout repository + uses: actions/checkout@v3 - name: Convert markdown to slack markdown for pull request - uses: LoveToKnow/slackify-markdown-action@v1.0.0 + uses: asyncapi/.github/.github/actions/slackify-markdown@master id: prmarkdown with: - text: "[${{github.event.pull_request.title}}](${{github.event.pull_request.html_url}}) \n ${{github.event.pull_request.body}}" + markdown: "[${{github.event.pull_request.title}}](${{github.event.pull_request.html_url}}) \n ${{github.event.pull_request.body}}" - name: Send info about pull request uses: rtCamp/action-slack-notify@v2 env: @@ -56,11 +60,13 @@ jobs: name: Notify slack on every new pull request runs-on: ubuntu-latest steps: + - name: Checkout repository + uses: actions/checkout@v3 - name: Convert markdown to slack markdown for pull request - uses: LoveToKnow/slackify-markdown-action@v1.0.0 + uses: asyncapi/.github/.github/actions/slackify-markdown@master id: discussionmarkdown with: - text: "[${{github.event.discussion.title}}](${{github.event.discussion.html_url}}) \n ${{github.event.discussion.body}}" + markdown: "[${{github.event.discussion.title}}](${{github.event.discussion.html_url}}) \n ${{github.event.discussion.body}}" - name: Send info about pull request uses: rtCamp/action-slack-notify@v2 env: diff --git a/.github/workflows/lint-pr-title.yml b/.github/workflows/lint-pr-title.yml index b3015a451..77aa1c6e4 100644 --- a/.github/workflows/lint-pr-title.yml +++ b/.github/workflows/lint-pr-title.yml @@ -14,7 +14,7 @@ jobs: steps: # Since this workflow is REQUIRED for a PR to be mergable, we have to have this 'if' statement in step level instead of job level. - if: ${{ !contains(fromJson('["asyncapi-bot", "dependabot[bot]", "dependabot-preview[bot]", "allcontributors[bot]"]'), github.actor) }} - uses: amannn/action-semantic-pull-request@505e44b4f33b4c801f063838b3f053990ee46ea7 #version 4.6.0 + uses: amannn/action-semantic-pull-request@c3cd5d1ea3580753008872425915e343e351ab54 #version 5.2.0 https://github.com/amannn/action-semantic-pull-request/releases/tag/v5.2.0 id: lint_pr_title env: GITHUB_TOKEN: ${{ secrets.GH_TOKEN}} @@ -26,7 +26,7 @@ jobs: # Comments the error message from the above lint_pr_title action - if: ${{ always() && steps.lint_pr_title.outputs.error_message != null && !contains(fromJson('["asyncapi-bot", "dependabot[bot]", "dependabot-preview[bot]", "allcontributors[bot]"]'), github.actor)}} name: Comment on PR - uses: marocchino/sticky-pull-request-comment@39c5b5dc7717447d0cba270cd115037d32d28443 #version 2.2 + uses: marocchino/sticky-pull-request-comment@3d60a5b2dae89d44e0c6ddc69dd7536aec2071cd #use 2.5.0 https://github.com/marocchino/sticky-pull-request-comment/releases/tag/v2.5.0 with: header: pr-title-lint-error GITHUB_TOKEN: ${{ secrets.GH_TOKEN}} @@ -40,7 +40,7 @@ jobs: # deletes the error comment if the title is correct - if: ${{ steps.lint_pr_title.outputs.error_message == null }} name: delete the comment - uses: marocchino/sticky-pull-request-comment@39c5b5dc7717447d0cba270cd115037d32d28443 #version 2.2 + uses: marocchino/sticky-pull-request-comment@3d60a5b2dae89d44e0c6ddc69dd7536aec2071cd #use 2.5.0 https://github.com/marocchino/sticky-pull-request-comment/releases/tag/v2.5.0 with: header: pr-title-lint-error delete: true diff --git a/.github/workflows/notify-tsc-members-mention.yml b/.github/workflows/notify-tsc-members-mention.yml index e681c18a0..d72fd85bd 100644 --- a/.github/workflows/notify-tsc-members-mention.yml +++ b/.github/workflows/notify-tsc-members-mention.yml @@ -31,14 +31,22 @@ jobs: name: TSC notification on every new issue runs-on: ubuntu-latest steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 16 + cache: 'npm' + cache-dependency-path: '**/package-lock.json' ######### # Handling Slack notifications ######### - name: Convert markdown to slack markdown - uses: LoveToKnow/slackify-markdown-action@v1.0.0 + uses: asyncapi/.github/.github/actions/slackify-markdown@master id: issuemarkdown with: - text: "[${{github.event.issue.title}}](${{github.event.issue.html_url}}) \n ${{github.event.issue.body}}" + markdown: "[${{github.event.issue.title}}](${{github.event.issue.html_url}}) \n ${{github.event.issue.body}}" - name: Send info about issue uses: rtCamp/action-slack-notify@v2 env: @@ -49,19 +57,11 @@ jobs: ######### # Handling Mailchimp notifications ######### - - name: Checkout repository - uses: actions/checkout@v2 - - name: Setup Node.js - uses: actions/setup-node@v2 - with: - node-version: 16 - cache: 'npm' - cache-dependency-path: '**/package-lock.json' - name: Install deps run: npm install working-directory: ./.github/workflows/scripts/mailchimp - name: Send email with MailChimp - uses: actions/github-script@v4 + uses: actions/github-script@v6 env: CALENDAR_ID: ${{ secrets.CALENDAR_ID }} CALENDAR_SERVICE_ACCOUNT: ${{ secrets.CALENDAR_SERVICE_ACCOUNT }} @@ -76,14 +76,22 @@ jobs: name: TSC notification on every new pull request runs-on: ubuntu-latest steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 16 + cache: 'npm' + cache-dependency-path: '**/package-lock.json' ######### # Handling Slack notifications ######### - name: Convert markdown to slack markdown - uses: LoveToKnow/slackify-markdown-action@v1.0.0 + uses: asyncapi/.github/.github/actions/slackify-markdown@master id: prmarkdown with: - text: "[${{github.event.pull_request.title}}](${{github.event.pull_request.html_url}}) \n ${{github.event.pull_request.body}}" + markdown: "[${{github.event.pull_request.title}}](${{github.event.pull_request.html_url}}) \n ${{github.event.pull_request.body}}" - name: Send info about pull request uses: rtCamp/action-slack-notify@v2 env: @@ -94,19 +102,11 @@ jobs: ######### # Handling Mailchimp notifications ######### - - name: Checkout repository - uses: actions/checkout@v2 - - name: Setup Node.js - uses: actions/setup-node@v2 - with: - node-version: 16 - cache: 'npm' - cache-dependency-path: '**/package-lock.json' - name: Install deps run: npm install working-directory: ./.github/workflows/scripts/mailchimp - name: Send email with MailChimp - uses: actions/github-script@v4 + uses: actions/github-script@v6 env: CALENDAR_ID: ${{ secrets.CALENDAR_ID }} CALENDAR_SERVICE_ACCOUNT: ${{ secrets.CALENDAR_SERVICE_ACCOUNT }} @@ -121,14 +121,22 @@ jobs: name: TSC notification on every new discussion runs-on: ubuntu-latest steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 16 + cache: 'npm' + cache-dependency-path: '**/package-lock.json' ######### # Handling Slack notifications ######### - name: Convert markdown to slack markdown - uses: LoveToKnow/slackify-markdown-action@v1.0.0 + uses: asyncapi/.github/.github/actions/slackify-markdown@master id: discussionmarkdown with: - text: "[${{github.event.discussion.title}}](${{github.event.discussion.html_url}}) \n ${{github.event.discussion.body}}" + markdown: "[${{github.event.discussion.title}}](${{github.event.discussion.html_url}}) \n ${{github.event.discussion.body}}" - name: Send info about pull request uses: rtCamp/action-slack-notify@v2 env: @@ -139,19 +147,11 @@ jobs: ######### # Handling Mailchimp notifications ######### - - name: Checkout repository - uses: actions/checkout@v2 - - name: Setup Node.js - uses: actions/setup-node@v2 - with: - node-version: 16 - cache: 'npm' - cache-dependency-path: '**/package-lock.json' - name: Install deps run: npm install working-directory: ./.github/workflows/scripts/mailchimp - name: Send email with MailChimp - uses: actions/github-script@v4 + uses: actions/github-script@v6 env: CALENDAR_ID: ${{ secrets.CALENDAR_ID }} CALENDAR_SERVICE_ACCOUNT: ${{ secrets.CALENDAR_SERVICE_ACCOUNT }} @@ -166,14 +166,22 @@ jobs: name: TSC notification on every new comment in issue runs-on: ubuntu-latest steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 16 + cache: 'npm' + cache-dependency-path: '**/package-lock.json' ######### # Handling Slack notifications ######### - name: Convert markdown to slack markdown - uses: LoveToKnow/slackify-markdown-action@v1.0.0 + uses: asyncapi/.github/.github/actions/slackify-markdown@master id: issuemarkdown with: - text: "[${{github.event.issue.title}}](${{github.event.comment.html_url}}) \n ${{github.event.comment.body}}" + markdown: "[${{github.event.issue.title}}](${{github.event.comment.html_url}}) \n ${{github.event.comment.body}}" - name: Send info about issue comment uses: rtCamp/action-slack-notify@v2 env: @@ -184,19 +192,11 @@ jobs: ######### # Handling Mailchimp notifications ######### - - name: Checkout repository - uses: actions/checkout@v2 - - name: Setup Node.js - uses: actions/setup-node@v2 - with: - node-version: 16 - cache: 'npm' - cache-dependency-path: '**/package-lock.json' - name: Install deps run: npm install working-directory: ./.github/workflows/scripts/mailchimp - name: Send email with MailChimp - uses: actions/github-script@v4 + uses: actions/github-script@v6 env: CALENDAR_ID: ${{ secrets.CALENDAR_ID }} CALENDAR_SERVICE_ACCOUNT: ${{ secrets.CALENDAR_SERVICE_ACCOUNT }} @@ -211,14 +211,22 @@ jobs: name: TSC notification on every new comment in pr runs-on: ubuntu-latest steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 16 + cache: 'npm' + cache-dependency-path: '**/package-lock.json' ######### # Handling Slack notifications ######### - name: Convert markdown to slack markdown - uses: LoveToKnow/slackify-markdown-action@v1.0.0 + uses: asyncapi/.github/.github/actions/slackify-markdown@master id: prmarkdown with: - text: "[${{github.event.issue.title}}](${{github.event.comment.html_url}}) \n ${{github.event.comment.body}}" + markdown: "[${{github.event.issue.title}}](${{github.event.comment.html_url}}) \n ${{github.event.comment.body}}" - name: Send info about PR comment uses: rtCamp/action-slack-notify@v2 env: @@ -229,19 +237,11 @@ jobs: ######### # Handling Mailchimp notifications ######### - - name: Checkout repository - uses: actions/checkout@v2 - - name: Setup Node.js - uses: actions/setup-node@v2 - with: - node-version: 16 - cache: 'npm' - cache-dependency-path: '**/package-lock.json' - name: Install deps run: npm install working-directory: ./.github/workflows/scripts/mailchimp - name: Send email with MailChimp - uses: actions/github-script@v4 + uses: actions/github-script@v6 env: CALENDAR_ID: ${{ secrets.CALENDAR_ID }} CALENDAR_SERVICE_ACCOUNT: ${{ secrets.CALENDAR_SERVICE_ACCOUNT }} @@ -256,14 +256,22 @@ jobs: name: TSC notification on every new comment in discussion runs-on: ubuntu-latest steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 16 + cache: 'npm' + cache-dependency-path: '**/package-lock.json' ######### # Handling Slack notifications ######### - name: Convert markdown to slack markdown - uses: LoveToKnow/slackify-markdown-action@v1.0.0 + uses: asyncapi/.github/.github/actions/slackify-markdown@master id: discussionmarkdown with: - text: "[${{github.event.discussion.title}}](${{github.event.comment.html_url}}) \n ${{github.event.comment.body}}" + markdown: "[${{github.event.discussion.title}}](${{github.event.comment.html_url}}) \n ${{github.event.comment.body}}" - name: Send info about discussion comment uses: rtCamp/action-slack-notify@v2 env: @@ -274,19 +282,11 @@ jobs: ######### # Handling Mailchimp notifications ######### - - name: Checkout repository - uses: actions/checkout@v2 - - name: Setup Node.js - uses: actions/setup-node@v2 - with: - node-version: 16 - cache: 'npm' - cache-dependency-path: '**/package-lock.json' - name: Install deps run: npm install working-directory: ./.github/workflows/scripts/mailchimp - name: Send email with MailChimp - uses: actions/github-script@v4 + uses: actions/github-script@v6 env: CALENDAR_ID: ${{ secrets.CALENDAR_ID }} CALENDAR_SERVICE_ACCOUNT: ${{ secrets.CALENDAR_SERVICE_ACCOUNT }} diff --git a/.github/workflows/release-announcements.yml b/.github/workflows/release-announcements.yml index b2f3ba76d..9587cacee 100644 --- a/.github/workflows/release-announcements.yml +++ b/.github/workflows/release-announcements.yml @@ -14,11 +14,13 @@ jobs: name: Slack - notify on every release runs-on: ubuntu-latest steps: + - name: Checkout repository + uses: actions/checkout@v3 - name: Convert markdown to slack markdown for issue - uses: LoveToKnow/slackify-markdown-action@v1.0.0 + uses: asyncapi/.github/.github/actions/slackify-markdown@master id: markdown with: - text: "[${{github.event.release.tag_name}}](${{github.event.release.html_url}}) \n ${{ github.event.release.body }}" + markdown: "[${{github.event.release.tag_name}}](${{github.event.release.html_url}}) \n ${{ github.event.release.body }}" - name: Send info about release to Slack uses: rtCamp/action-slack-notify@v2 env: @@ -32,9 +34,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Get version of last and previous release - uses: actions/github-script@v3 + uses: actions/github-script@v6 id: versions with: github-token: ${{ secrets.GITHUB_TOKEN }} @@ -60,15 +62,15 @@ jobs: - name: Identify release type id: releasetype # if previousver is not provided then this steps just logs information about missing version, no errors - run: echo "::set-output name=type::$(npx -q -p semver-diff-cli semver-diff ${{steps.versions.outputs.previousver}} ${{steps.versions.outputs.lastver}})" + run: echo "type=$(npx -q -p semver-diff-cli semver-diff ${{steps.versions.outputs.previousver}} ${{steps.versions.outputs.lastver}})" >> $GITHUB_OUTPUT - name: Get name of the person that is behind the newly released version id: author - run: echo "::set-output name=name::$(git log -1 --pretty=format:'%an')" + run: echo "name=$(git log -1 --pretty=format:'%an')" >> $GITHUB_OUTPUT - name: Publish information about the release to Twitter # tweet only if detected version change is not a patch # tweet goes out even if the type is not major or minor but "You need provide version number to compare." # it is ok, it just means we did not identify previous version as we are tweeting out information about the release for the first time if: steps.releasetype.outputs.type != 'null' && steps.releasetype.outputs.type != 'patch' # null means that versions are the same - uses: m1ner79/Github-Twittction@v1.0.1 + uses: m1ner79/Github-Twittction@d1e508b6c2170145127138f93c49b7c46c6ff3a7 # using 2.0.0 https://github.com/m1ner79/Github-Twittction/releases/tag/v2.0.0 with: twitter_status: "Release ${{github.event.release.tag_name}} for ${{github.repository}} is out in the wild 😱💪🍾🎂\n\nThank you for the contribution ${{ steps.author.outputs.name }} ${{github.event.release.html_url}}" twitter_consumer_key: ${{ secrets.TWITTER_CONSUMER_KEY }} diff --git a/.github/workflows/sentiment-analysis.yml b/.github/workflows/sentiment-analysis.yml deleted file mode 100644 index f1f845a0d..000000000 --- a/.github/workflows/sentiment-analysis.yml +++ /dev/null @@ -1,45 +0,0 @@ -# This action is centrally managed in https://github.com/asyncapi/.github/ -# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo - -name: 'Sentiment Analysis' - -on: - issue_comment: - types: - - created - - edited - issues: - types: - - opened - - edited - pull_request: - types: - - opened - - edited - pull_request_review: - types: - - submitted - - edited - pull_request_review_comment: - types: - - created - - edited -jobs: - sentiments: - if: ${{ !contains(fromJson('["asyncapi-bot", "dependabot[bot]", "dependabot-preview[bot]", "allcontributors[bot]"]'), github.actor) }} - name: Checking sentiments - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Check sentiment - uses: derberg/code-of-conduct-sentiment-analysis-github-action@v1 - id: sentiments - with: - gcp_key: ${{ secrets.GCP_KEY_SENTIMENT }} - - uses: someimportantcompany/github-actions-slack-message@v1 - # this step runs only if sentiment is a negative number - if: steps.sentiments.outputs.sentiment < -0.6 - with: - webhook-url: ${{ secrets.SLACK_SENTIMENTS }} - text: Here ${{steps.sentiments.outputs.source}} you can find a potential negative text that requires your attention as the sentiment analysis score is ${{steps.sentiments.outputs.sentiment}} - color: orange \ No newline at end of file diff --git a/.github/workflows/welcome-first-time-contrib.yml b/.github/workflows/welcome-first-time-contrib.yml index 34fb25d20..cbc23ce7c 100644 --- a/.github/workflows/welcome-first-time-contrib.yml +++ b/.github/workflows/welcome-first-time-contrib.yml @@ -17,7 +17,7 @@ jobs: if: ${{ !contains(fromJson('["asyncapi-bot", "dependabot[bot]", "dependabot-preview[bot]", "allcontributors[bot]"]'), github.actor) }} runs-on: ubuntu-latest steps: - - uses: actions/github-script@v3 + - uses: actions/github-script@v6 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | @@ -65,7 +65,7 @@ jobs: if (isIssue) { const issueNumber = context.payload.issue.number; console.log(`Adding message: ${message} to issue #${issueNumber}`); - await github.issues.createComment({ + await github.rest.issues.createComment({ owner: context.payload.repository.owner.login, repo: context.payload.repository.name, issue_number: issueNumber, @@ -75,7 +75,7 @@ jobs: else { const pullNumber = context.payload.pull_request.number; console.log(`Adding message: ${message} to pull request #${pullNumber}`); - await github.pulls.createReview({ + await github.rest.pulls.createReview({ owner: context.payload.repository.owner.login, repo: context.payload.repository.name, pull_number: pullNumber, From da9ed1ccb56bc8fc9d6be0b0d6e0f7bd31be3a3b Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Thu, 13 Apr 2023 16:26:49 +0200 Subject: [PATCH 20/37] ci: update generic workflows (#925) Co-authored-by: asyncapi-bot --- .../scripts/mailchimp/package-lock.json | 63 +++++++------------ .../workflows/scripts/mailchimp/package.json | 2 +- 2 files changed, 25 insertions(+), 40 deletions(-) diff --git a/.github/workflows/scripts/mailchimp/package-lock.json b/.github/workflows/scripts/mailchimp/package-lock.json index 089364fa8..7ee7d84f8 100644 --- a/.github/workflows/scripts/mailchimp/package-lock.json +++ b/.github/workflows/scripts/mailchimp/package-lock.json @@ -7,25 +7,24 @@ "name": "schedule-email", "license": "Apache 2.0", "dependencies": { - "@actions/core": "1.9.1", + "@actions/core": "1.6.0", "@mailchimp/mailchimp_marketing": "3.0.74" } }, "node_modules/@actions/core": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz", - "integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.6.0.tgz", + "integrity": "sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw==", "dependencies": { - "@actions/http-client": "^2.0.1", - "uuid": "^8.3.2" + "@actions/http-client": "^1.0.11" } }, "node_modules/@actions/http-client": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz", - "integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz", + "integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==", "dependencies": { - "tunnel": "^0.0.6" + "tunnel": "0.0.6" } }, "node_modules/@mailchimp/mailchimp_marketing": { @@ -74,9 +73,9 @@ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "node_modules/cookiejar": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", - "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", + "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==" }, "node_modules/core-util-is": { "version": "1.0.3", @@ -332,32 +331,23 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } } }, "dependencies": { "@actions/core": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz", - "integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.6.0.tgz", + "integrity": "sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw==", "requires": { - "@actions/http-client": "^2.0.1", - "uuid": "^8.3.2" + "@actions/http-client": "^1.0.11" } }, "@actions/http-client": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz", - "integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz", + "integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==", "requires": { - "tunnel": "^0.0.6" + "tunnel": "0.0.6" } }, "@mailchimp/mailchimp_marketing": { @@ -397,9 +387,9 @@ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "cookiejar": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", - "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", + "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==" }, "core-util-is": { "version": "1.0.3", @@ -602,11 +592,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" } } -} +} \ No newline at end of file diff --git a/.github/workflows/scripts/mailchimp/package.json b/.github/workflows/scripts/mailchimp/package.json index 28b447ff7..cc50e43e0 100644 --- a/.github/workflows/scripts/mailchimp/package.json +++ b/.github/workflows/scripts/mailchimp/package.json @@ -3,7 +3,7 @@ "description": "This code is responsible for scheduling an email campaign. This file is centrally managed in https://github.com/asyncapi/.github/", "license": "Apache 2.0", "dependencies": { - "@actions/core": "1.9.1", + "@actions/core": "1.6.0", "@mailchimp/mailchimp_marketing": "3.0.74" } } \ No newline at end of file From 33dfa1192ff68179afc9c0757430d283ccf29b84 Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Thu, 13 Apr 2023 16:41:03 +0200 Subject: [PATCH 21/37] ci: update generic workflows (#927) Co-authored-by: asyncapi-bot --- .github/workflows/automerge.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index 6dab60945..9253675cd 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -1,7 +1,7 @@ # This action is centrally managed in https://github.com/asyncapi/.github/ # Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo. -name: Automerge release bump PR +name: Automerge PRs from bots on: pull_request_target: @@ -41,7 +41,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Automerging - uses: pascalgn/automerge-action@22948e0bc22f0aa673800da838595a3e7347e584 #v0.15.6 https://github.com/pascalgn/automerge-action/releases/tag/v0.15.6 + uses: pascalgn/automerge-action@22948e0bc22f0aa673800da838595a3e7347e584 #v0.15.6 https://github.com/pascalgn/automerge-action/releases/tag/v0.15.6 env: GITHUB_TOKEN: "${{ secrets.GH_TOKEN }}" GITHUB_LOGIN: asyncapi-bot From ef33aef4e4d5c5b5047366fa0387213cf61d0c08 Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Thu, 29 Jun 2023 15:14:32 +0200 Subject: [PATCH 22/37] ci: update of files from global .github repo (#951) --- .github/workflows/help-command.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/help-command.yml b/.github/workflows/help-command.yml index f4955c221..d4ba4a44c 100644 --- a/.github/workflows/help-command.yml +++ b/.github/workflows/help-command.yml @@ -27,13 +27,13 @@ jobs: repo: context.repo.repo, body: `Hello, @${{ github.actor }}! 👋🏼 - I'm Genie from the magic lamp. Looks like somebody needs a hand! 🆘 + I'm 🧞🧞🧞 Genie 🧞🧞🧞 from the magic lamp. Looks like somebody needs a hand! At the moment the following comments are supported in pull requests: - - `/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 or it is a draft PR.` + - \`/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 or it is a draft PR.` }) create_help_comment_issue: @@ -51,10 +51,10 @@ jobs: repo: context.repo.repo, body: `Hello, @${{ github.actor }}! 👋🏼 - I'm Genie from the magic lamp. Looks like somebody needs a hand! 🆘 + I'm 🧞🧞🧞 Genie 🧞🧞🧞 from the magic lamp. Looks like somebody needs a hand! At the moment the following comments are supported in issues: - - `/good-first-issue {js | ts | java | go | docs | design | ci-cd} ` or `/gfi {js | ts | java | go | docs | design | ci-cd} ` - label an issue as a `good first issue`. - example: `/gfi js` or `/good-first-issue ci-cd` - }) + - \`/good-first-issue {js | ts | java | go | docs | design | ci-cd}\` or \`/gfi {js | ts | java | go | docs | design | ci-cd}\` - label an issue as a \`good first issue\`. + example: \`/gfi js\` or \`/good-first-issue ci-cd\`` + }) \ No newline at end of file From 268d79d4c5637b117baf7187ecf67626bfd31aac Mon Sep 17 00:00:00 2001 From: Rishi <52498617+kaushik-rishi@users.noreply.github.com> Date: Tue, 25 Jul 2023 15:50:45 +0530 Subject: [PATCH 23/37] ci: update release workflow (#939) --- .github/workflows/release.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8252eadd8..34ce3e2d0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,11 +13,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 + with: + node-version: 18 - name: Add plugin for conventional commits - run: npm install conventional-changelog-conventionalcommits + run: npm install --save-dev conventional-changelog-conventionalcommits@5.0.0 - name: Release to GitHub env: GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} From 121ea2b09af6ef57b3cd0c01baeb28f0f869e87c Mon Sep 17 00:00:00 2001 From: Lukasz Gornicki Date: Fri, 11 Aug 2023 12:43:16 +0200 Subject: [PATCH 24/37] ci: upgrade GH workflows and fix markdown linting (#958) --- .github/workflows/lint.yml | 9 +- .github/workflows/new-spec-release.yml | 14 +-- .github/workflows/update-spec.yaml | 6 +- .markdownlint.yaml | 9 ++ CONTRIBUTING.md | 8 ++ mlc_config.json | 19 --- spec/asyncapi.md | 164 +++++++++---------------- 7 files changed, 89 insertions(+), 140 deletions(-) create mode 100644 .markdownlint.yaml delete mode 100644 mlc_config.json diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 0fab4bd20..2b23e7fbe 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,15 +1,16 @@ -name: Lint +name: Lint specification markdown file on: pull_request: types: [opened, reopened, synchronize, ready_for_review] + paths: + - 'spec/asyncapi.md' jobs: lint: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Run linter - run: npx mdv spec/*.md - + run: docker run -v $PWD:/workdir ghcr.io/igorshubovych/markdownlint-cli:v0.35.0 "spec/asyncapi.md" \ No newline at end of file diff --git a/.github/workflows/new-spec-release.yml b/.github/workflows/new-spec-release.yml index eadf1fda3..11c59cd0b 100644 --- a/.github/workflows/new-spec-release.yml +++ b/.github/workflows/new-spec-release.yml @@ -13,12 +13,12 @@ jobs: GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} steps: - name: Checkout Current repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: spec ref: ${{ github.event.release.target_commitish }} - name: Checkout Another repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: asyncapi/website path: website @@ -32,7 +32,7 @@ jobs: run: | git checkout -b spec-release-${{github.event.release.tag_name}} - name: Check for previous spec file and remove it - uses: actions/github-script@v3 + uses: actions/github-script@v6 with: github-token: ${{ env.GITHUB_TOKEN }} script: | @@ -53,14 +53,14 @@ jobs: run: | 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 + uses: actions/github-script@v6 with: github-token: ${{ env.GITHUB_TOKEN }} script: | const script = require('./spec/.github/scripts/remove-toc'); script(`${{github.event.release.tag_name}}`); - name: Change the redirect file to point to latest spec - uses: actions/github-script@v3 + uses: actions/github-script@v6 if: ${{github.event.release.prerelease == false}} with: github-token: ${{ env.GITHUB_TOKEN }} @@ -90,7 +90,7 @@ jobs: fs.writeFileSync("./website/public/_redirects", newRedirect); - name: Remove previous pre-release redirects in case of a new release - uses: actions/github-script@v3 + uses: actions/github-script@v6 with: github-token: ${{ env.GITHUB_TOKEN }} script: | @@ -125,7 +125,7 @@ jobs: fs.writeFileSync("./website/public/_redirects", newRedirect); - name: Change the redirect file to point to specs - uses: actions/github-script@v3 + uses: actions/github-script@v6 with: github-token: ${{ env.GITHUB_TOKEN }} script: | diff --git a/.github/workflows/update-spec.yaml b/.github/workflows/update-spec.yaml index d5ad7aa1e..49b2481b2 100644 --- a/.github/workflows/update-spec.yaml +++ b/.github/workflows/update-spec.yaml @@ -15,11 +15,11 @@ jobs: GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} steps: - name: Checkout Current repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: spec - name: Checkout Another repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: asyncapi/website path: website @@ -43,7 +43,7 @@ jobs: run: | 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 + uses: actions/github-script@v6 with: github-token: ${{ env.GITHUB_TOKEN }} script: | diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 000000000..7b77ce976 --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,9 @@ +# MD013/line-length - Line length +# We should keep it disabled as this line length limit do not maeke sense really +MD013: false +# MD033/no-inline-html - Inline HTML +# We use HTML links in deadings all over the place. Probably this is why links in GitHub do not work, but that requires investingation if we can remove them really +MD033: false +# MD024/no-duplicate-heading/no-duplicate-header - Multiple headings with the same content +# For now hard to say how that should be fixed as we have such duplicates like Fixed Fields all over the place +MD024: false \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c82242d80..d096c5f46 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -243,6 +243,14 @@ A pull request can be merged if all the following conditions are met: * There is, at least, a mininum of 3 approvals from the [repository code owners](./CODEOWNERS). * Sufficient time has passed to let all code owners review the pull request. As of now, it should be a minimum of 1 week. If all code owners have already approved a pull request, it's ok not to wait for this period of time. +## Linting specification document + +Always make sure that the specification markdown file has no markdown-related errors. + +Instead of waiting for GitHub Actions workflow to check markdown file, you can do it locally by calling the following docker command: +```bash +docker run -v $PWD:/workdir ghcr.io/igorshubovych/markdownlint-cli:v0.35.0 "spec/asyncapi.md" +``` ## References This document was adapted from the [GraphQL Specification Contribution Guide](https://github.com/graphql/graphql-spec/blob/main/CONTRIBUTING.md). \ No newline at end of file diff --git a/mlc_config.json b/mlc_config.json deleted file mode 100644 index 01833db7f..000000000 --- a/mlc_config.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "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 1fb6c8bd4..26bbd7f33 100644 --- a/spec/asyncapi.md +++ b/spec/asyncapi.md @@ -1,10 +1,10 @@ # AsyncAPI Specification -#### Disclaimer +## Disclaimer 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.6.0 +## Version 2.6.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). @@ -86,29 +86,37 @@ It means that the [application](#definitionsApplication) allows [consumers](#def ## Definitions -#### Server +### Server + A server MAY be a message broker that is capable of sending and/or receiving between a [producer](#definitionsProducer) and [consumer](#definitionsConsumer). A server MAY be a service with WebSocket API that enables message-driven communication between browser-to-server or server-to-server. -#### Application -An application is any kind of computer program or a group of them. It MUST be a [producer](#definitionsProducer), a [consumer](#definitionsConsumer) or both. An application MAY be a microservice, IoT device (sensor), mainframe process, etc. An application MAY be written in any number of different programming languages as long as they support the selected [protocol](#definitionsProtocol). An application MUST also use a protocol supported by the [server](#definitionsServer) in order to connect and exchange [messages](#definitionsMessage). +### Application + +An application is any kind of computer program or a group of them. It MUST be a [producer](#definitionsProducer), a [consumer](#definitionsConsumer) or both. An application MAY be a microservice, IoT device (sensor), mainframe process, etc. An application MAY be written in any number of different programming languages as long as they support the selected [protocol](#definitionsProtocol). An application MUST also use a protocol supported by the [server](#definitionsServer) in order to connect and exchange [messages](#definitionsMessage). + +### Producer -#### Producer A producer is a type of application, connected to a [server](#definitionsServer), that is creating [messages](#definitionsMessage) and addressing them to [channels](#definitionsChannel). A producer MAY be publishing to multiple channels depending on the [server](#definitionsServer), protocol, and use-case pattern. -#### Consumer +### Consumer + A consumer is a type of application, connected to a [server](#definitionsServer) via a supported [protocol](#definitionsProtocol), that is consuming [messages](#definitionsMessage) from [channels](#definitionsChannel). A consumer MAY be consuming from multiple channels depending on the [server](#definitionsServer), protocol, and the use-case pattern. -#### Message -A message is the mechanism by which information is exchanged via a channel between [servers](#definitionsServer) and applications. A message MUST contain a payload and MAY also contain headers. The headers MAY be subdivided into [protocol](#definitionsProtocol)-defined headers and header properties defined by the application which can act as supporting metadata. The payload contains the data, defined by the application, which MUST be serialized into a format (JSON, XML, Avro, binary, etc.). Since a message is a generic mechanism, it can support multiple interaction patterns such as event, command, request, or response. +### Message + +A message is the mechanism by which information is exchanged via a channel between [servers](#definitionsServer) and applications. A message MUST contain a payload and MAY also contain headers. The headers MAY be subdivided into [protocol](#definitionsProtocol)-defined headers and header properties defined by the application which can act as supporting metadata. The payload contains the data, defined by the application, which MUST be serialized into a format (JSON, XML, Avro, binary, etc.). Since a message is a generic mechanism, it can support multiple interaction patterns such as event, command, request, or response. + +### Channel -#### Channel A channel is an addressable component, made available by the [server](#definitionsServer), for the organization of [messages](#definitionsMessage). [Producer](#definitionsProducer) applications send messages to channels and [consumer](#definitionsConsumer) applications consume messages from channels. [Servers](#definitionsServer) MAY support many channel instances, allowing messages with different content to be addressed to different channels. Depending on the [server](#definitionsServer) implementation, the channel MAY be included in the message via protocol-defined headers. -#### Protocol +### Protocol + A protocol is the mechanism (wireline protocol or API) by which [messages](#definitionsMessage) are exchanged between the application and the [channel](#definitionsChannel). Example protocols include, but are not limited to, AMQP, HTTP, JMS, Kafka, Anypoint MQ, MQTT, Solace, STOMP, Mercure, WebSocket, Google Pub/Sub, Pulsar. -#### Bindings -A "binding" (or "protocol binding") is a mechanism to define protocol-specific information. Therefore, a protocol binding MUST define protocol-specific information only. +### Bindings + +A "binding" (or "protocol binding") is a mechanism to define protocol-specific information. Therefore, a protocol binding MUST define protocol-specific information only. ## Specification @@ -170,7 +178,6 @@ Field Name | Type | Description 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 MAY be extended with [Specification Extensions](#specificationExtensions). #### AsyncAPI Version String @@ -189,7 +196,7 @@ This field represents a unique universal identifier of the [application](#defini It is RECOMMENDED to use a [URN](https://tools.ietf.org/html/rfc8141) to globally and uniquely identify the application during long periods of time, even after it becomes unavailable or ceases to exist. -###### Examples +##### Examples ```json { @@ -229,7 +236,7 @@ Field Name | Type | Description This object MAY be extended with [Specification Extensions](#specificationExtensions). -##### Info Object Example: +##### Info Object Example ```json { @@ -277,7 +284,7 @@ Field Name | Type | Description This object MAY be extended with [Specification Extensions](#specificationExtensions). -##### Contact Object Example: +##### Contact Object Example ```json { @@ -306,7 +313,7 @@ Field Name | Type | Description This object MAY be extended with [Specification Extensions](#specificationExtensions). -##### License Object Example: +##### License Object Example ```json { @@ -351,7 +358,6 @@ production: protocolVersion: '1.0.0' ``` - #### Server Object An object representing a message broker, a server or any other kind of computer program capable of sending and/or receiving data. This object is used to capture details such as URIs, protocols and security configuration. Variable substitution can be used so that some details, for example usernames and passwords, can be injected by code generation tools. @@ -515,7 +521,6 @@ servers: default: v2 ``` - #### Server Variable Object An object representing a Server Variable for server URL template substitution. @@ -531,10 +536,6 @@ Field Name | Type | Description This object MAY be extended with [Specification Extensions](#specificationExtensions). - - - - #### Default Content Type A string representing the default content type to use when encoding/decoding a message's payload. The value MUST be a specific media type (e.g. `application/json`). This value MUST be used by schema parsers when the [contentType](#messageObjectContentType) property is omitted. @@ -553,11 +554,6 @@ In case a message can't be encoded/decoded using this value, schema parsers MUST defaultContentType: application/json ``` - - - - - #### Channels Object Holds the relative paths to the individual channel and their operations. Channel paths are relative to servers. @@ -591,9 +587,6 @@ user/signedup: $ref: "#/components/messages/userSignedUp" ``` - - - #### Channel Item Object Describes the operations available on a single channel. @@ -602,7 +595,7 @@ Describes the operations available on a single channel. Field Name | Type | Description ---|:---:|--- -$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. +$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. @@ -688,7 +681,6 @@ subscribe: - $ref: '#/components/messages/login' ``` - Using explicit by-name references to the servers on which the channel is available: ```json @@ -724,10 +716,6 @@ bindings: is: queue ``` - - - - #### Operation Object Describes a publish or a subscribe operation. This provides a place to document how and why messages are sent and received. @@ -836,9 +824,6 @@ traits: - $ref: "#/components/operationTraits/kafka" ``` - - - #### Operation Trait Object Describes a trait that MAY be applied to an [Operation Object](#operationObject). This object MAY contain any property from the [Operation Object](#operationObject), except `message` and `traits`. @@ -877,9 +862,6 @@ bindings: ack: false ``` - - - #### Parameters Object Describes a map of parameters included in a channel name. @@ -926,10 +908,6 @@ user/{userId}/signup: $ref: "#/components/messages/userSignedUp" ``` - - - - #### Parameter Object Describes a parameter included in a channel name. @@ -980,9 +958,6 @@ user/{userId}/signup: $ref: "#/components/messages/userSignedUp" ``` - - - #### Server Bindings Object Map describing protocol-specific definitions for a server. @@ -1013,8 +988,6 @@ Field Name | Type | Description This object MAY be extended with [Specification Extensions](#specificationExtensions). - - #### Channel Bindings Object Map describing protocol-specific definitions for a channel. @@ -1045,8 +1018,6 @@ Field Name | Type | Description This object MAY be extended with [Specification Extensions](#specificationExtensions). - - #### Operation Bindings Object Map describing protocol-specific definitions for an operation. @@ -1077,9 +1048,6 @@ Field Name | Type | Description This object MAY be extended with [Specification Extensions](#specificationExtensions). - - - #### Message Bindings Object Map describing protocol-specific definitions for a message. @@ -1110,12 +1078,6 @@ Field Name | Type | Description This object MAY be extended with [Specification Extensions](#specificationExtensions). - - - - - - #### Message Object Describes a message received on a given channel and operation. @@ -1149,17 +1111,16 @@ The following table contains a set of values that every implementation MUST supp Name | Allowed values | Notes ---|:---:|--- [AsyncAPI 2.6.0 Schema Object](#schemaObject) | `application/vnd.aai.asyncapi;version=2.6.0`, `application/vnd.aai.asyncapi+json;version=2.6.0`, `application/vnd.aai.asyncapi+yaml;version=2.6.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` | +[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. Name | Allowed values | Notes ---|:---:|--- [Avro 1.9.0 schema](https://avro.apache.org/docs/1.9.0/spec.html#schemas) | `application/vnd.apache.avro;version=1.9.0`, `application/vnd.apache.avro+json;version=1.9.0`, `application/vnd.apache.avro+yaml;version=1.9.0` | -[OpenAPI 3.0.0 Schema Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaObject) | `application/vnd.oai.openapi;version=3.0.0`, `application/vnd.oai.openapi+json;version=3.0.0`, `application/vnd.oai.openapi+yaml;version=3.0.0` | +[OpenAPI 3.0.0 Schema Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaObject) | `application/vnd.oai.openapi;version=3.0.0`, `application/vnd.oai.openapi+json;version=3.0.0`, `application/vnd.oai.openapi+yaml;version=3.0.0` | [RAML 1.0 data type](https://github.com/raml-org/raml-spec/blob/master/versions/raml-10/raml-10.md/) | `application/raml+yaml;version=1.0` | - ##### Message Object Example ```json @@ -1308,12 +1269,6 @@ payload: $ref: 'path/to/user-create.avsc/#UserCreate' ``` - - - - - - #### Message Trait Object Describes a trait that MAY be applied to a [Message Object](#messageObject). This object MAY contain any property from the [Message Object](#messageObject), except `payload` and `traits`. @@ -1356,13 +1311,13 @@ contentType: application/json #### Message Example Object -Message Example Object represents an example of a [Message Object](#messageObject) and MUST contain either **headers** and/or **payload** fields. +Message Example Object represents an example of a [Message Object](#messageObject) and MUST contain either **headers** and/or **payload** fields. ##### Fixed Fields Field Name | Type | Description ---|:---:|--- -headers | `Map[string, any]` | The value of this field MUST validate against the [Message Object's headers](#messageObjectHeaders) field. +headers | `Map[string, any]` | The value of this field MUST validate against the [Message Object's headers](#messageObjectHeaders) field. payload | `any` | The value of this field MUST validate against the [Message Object's payload](#messageObjectPayload) field. name | `string` | A machine-friendly name. summary | `string` | A short summary of what the example is about. @@ -1412,6 +1367,7 @@ A Tags object is a list of Tag Objects. Allows adding meta data to a single tag. ##### Fixed Fields + Field Name | Type | Description ---|:---:|--- name | `string` | **REQUIRED.** The name of the tag. @@ -1424,8 +1380,8 @@ This object MAY be extended with [Specification Extensions](#specificationExtens ```json { - "name": "user", - "description": "User-related messages" + "name": "user", + "description": "User-related messages" } ``` @@ -1434,12 +1390,6 @@ name: user description: User-related messages ``` - - - - - - #### External Documentation Object Allows referencing an external resource for extended documentation. @@ -1476,6 +1426,7 @@ The Reference Object is defined by [JSON Reference](https://tools.ietf.org/html/ For this specification, reference resolution is done as defined by the JSON Reference specification and not by the JSON Schema specification. ##### Fixed Fields + Field Name | Type | Description ---|:---:|--- $ref | `string` | **REQUIRED.** The reference string. @@ -1502,10 +1453,10 @@ All objects defined within the components object will have no effect on the API ##### Fixed Fields Field Name | Type | Description ----|:---|--- +---|:---|--- schemas | Map[`string`, [Schema Object](#schemaObject) \| [Reference Object](#referenceObject)] | An object to hold reusable [Schema Objects](#schemaObject). servers | Map[`string`, [Server Object](#serverObject) \| [Reference Object](#referenceObject)] | An object to hold reusable [Server Objects](#serverObject). - serverVariables | Map[`string`, [Server Variable Object](#serverVariableObject) \| [Reference Object](#referenceObject)] | An object to hold reusable [Server Variable Objects](#serverVariableObject). + serverVariables | Map[`string`, [Server Variable Object](#serverVariableObject) \| [Reference Object](#referenceObject)] | An object to hold reusable [Server Variable Objects](#serverVariableObject). channels | Map[`string`, [Channel Item Object](#channelItemObject)] | An object to hold reusable [Channel Item Objects](#channelItemObject). messages | Map[`string`, [Message Object](#messageObject) \| [Reference Object](#referenceObject)] | An object to hold reusable [Message Objects](#messageObject). securitySchemes| Map[`string`, [Security Scheme Object](#securitySchemeObject) \| [Reference Object](#referenceObject)] | An object to hold reusable [Security Scheme Objects](#securitySchemeObject). @@ -1524,7 +1475,7 @@ All the fixed fields declared above are objects that MUST use keys that match th Field Name Examples: -``` +```plaintext User User_1 User_Name @@ -1805,6 +1756,7 @@ Alternatively, any time a Schema Object can be used, a [Reference Object](#refer In addition to the JSON Schema fields, the following AsyncAPI vocabulary fields MAY be used for further schema documentation: ##### Fixed Fields + Field Name | Type | Description ---|:---:|--- discriminator | `string` | Adds support for polymorphism. The discriminator is the schema property name that is used to differentiate between other schema that inherit this schema. The property name used MUST be defined at this schema and it MUST be in the `required` property list. When used, the value MUST be the name of this schema or any schema that inherits it. See [Composition and Inheritance](#schemaComposition) for more details. @@ -1816,7 +1768,7 @@ This object MAY be extended with [Specification Extensions](#specificationExtens ###### Composition and Inheritance (Polymorphism) The AsyncAPI Specification allows combining and extending model definitions using the `allOf` property of JSON Schema, in effect offering model composition. -`allOf` takes in an array of object definitions that are validated *independently* but together compose a single object. +`allOf` takes in an array of object definitions that are validated _independently_ but together compose a single object. While composition offers model extensibility, it does not imply a hierarchy between the models. To support polymorphism, AsyncAPI Specification adds the support of the `discriminator` field. @@ -1827,7 +1779,7 @@ There are two ways to define the value of a discriminator for an inheriting inst - Use the schema's name. - Override the schema's name by overriding the property with a new value. If exists, this takes precedence over the schema's name. -As such, inline schema definitions, which do not have a given id, *cannot* be used in polymorphism. +As such, inline schema definitions, which do not have a given id, _cannot_ be used in polymorphism. ##### Schema Object Examples @@ -2212,25 +2164,22 @@ schemas: - color ``` - - - - #### Security Scheme Object Defines a security scheme that can be used by the operations. Supported schemes are: -* User/Password. -* API key (either as user or as password). -* X.509 certificate. -* End-to-end encryption (either symmetric or asymmetric). -* HTTP authentication. -* HTTP API key. -* OAuth2's common flows (Implicit, Resource Owner Protected Credentials, Client Credentials and Authorization Code) as defined in [RFC6749](https://tools.ietf.org/html/rfc6749). -* [OpenID Connect Discovery](https://tools.ietf.org/html/draft-ietf-oauth-discovery-06). -* SASL (Simple Authentication and Security Layer) as defined in [RFC4422](https://tools.ietf.org/html/rfc4422). +- User/Password. +- API key (either as user or as password). +- X.509 certificate. +- End-to-end encryption (either symmetric or asymmetric). +- HTTP authentication. +- HTTP API key. +- OAuth2's common flows (Implicit, Resource Owner Protected Credentials, Client Credentials and Authorization Code) as defined in [RFC6749](https://tools.ietf.org/html/rfc6749). +- [OpenID Connect Discovery](https://tools.ietf.org/html/draft-ietf-oauth-discovery-06). +- SASL (Simple Authentication and Security Layer) as defined in [RFC4422](https://tools.ietf.org/html/rfc4422). ##### Fixed Fields + Field Name | Type | Applies To | Description ---|:---:|---|--- type | `string` | Any | **REQUIRED**. The type of the security scheme. Valid values are `"userPassword"`, `"apiKey"`, `"X509"`, `"symmetricEncryption"`, `"asymmetricEncryption"`, `"httpApiKey"`, `"http"`, `"oauth2"`, `"openIdConnect"`, `"plain"`, `"scramSha256"`, `"scramSha512"`, and `"gssapi"`. @@ -2386,6 +2335,7 @@ type: scramSha512 Allows configuration of the supported OAuth Flows. ##### Fixed Fields + Field Name | Type | Description ---|:---:|--- implicit| [OAuth Flow Object](#oauthFlowObject) | Configuration for the OAuth Implicit flow. @@ -2400,6 +2350,7 @@ This object MAY be extended with [Specification Extensions](#specificationExtens 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 an absolute URL. @@ -2508,11 +2459,11 @@ petstore_auth: ### Correlation ID Object -An object that specifies an identifier at design time that can used for message tracing and correlation. +An object that specifies an identifier at design time that can used for message tracing and correlation. For specifying and computing the location of a Correlation ID, a [runtime expression](#runtimeExpression) is used. -##### Fixed Fields +#### Fixed Fields Field Name | Type | Description ---|:---|--- @@ -2521,7 +2472,7 @@ location | `string` | **REQUIRED.** A [runtime expression](#runtimeExpression) t This object MAY be extended with [Specification Extensions](#specificationExtensions). -##### Examples +#### Examples ```json { @@ -2542,7 +2493,7 @@ This mechanism is used by [Correlation ID Object](#correlationIdObject). The runtime expression is defined by the following [ABNF](https://tools.ietf.org/html/rfc5234) syntax: -``` +```plaintext expression = ( "$message" "." source ) source = ( header-reference | payload-reference ) header-reference = "header" ["#" fragment] @@ -2552,7 +2503,7 @@ The runtime expression is defined by the following [ABNF](https://tools.ietf.org The table below provides examples of runtime expressions and examples of their use in a value: -##### Examples +#### Examples Source Location | Example expression | Notes ---|:---|:---| @@ -2584,7 +2535,6 @@ Tools that do not recognize a specific `format` MAY default back to the `type` a The formats defined by the AsyncAPI Specification are: - Common Name | `type` | [`format`](#dataTypeFormat) | Comments ----------- | ------ | -------- | -------- integer | `integer` | `int32` | signed 32 bits From ca429e60126ff5635d9deca05061a9cd1122ef39 Mon Sep 17 00:00:00 2001 From: Darren Dsouza <130863032+DarrenDsouza7273@users.noreply.github.com> Date: Tue, 29 Aug 2023 20:47:55 +0530 Subject: [PATCH 25/37] docs: add bronze sponsors (#964) --- README.md | 13 +++++++++++++ assets/ably.png | Bin 0 -> 19105 bytes assets/rviewer.png | Bin 0 -> 34837 bytes 3 files changed, 13 insertions(+) create mode 100644 assets/ably.png create mode 100644 assets/rviewer.png diff --git a/README.md b/README.md index c198d686e..3fd000278 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,19 @@ Check out the [examples](https://github.com/asyncapi/asyncapi/blob/master/exampl

+### Bronze + +

+ + + ably.png logo + +      + + rviewer.png logo + +      +

## Contributors diff --git a/assets/ably.png b/assets/ably.png new file mode 100644 index 0000000000000000000000000000000000000000..b451373d2414a8afcd553a370ed3224084c8241c GIT binary patch literal 19105 zcmXtfbyySZ_xHx=M!Hiz{26EL9WNC1E`zmlxfdmrFQn^V2fq9@gD#q^y8 zC&ynSH$|eK()d_I${(3_fCP)hQz(ViTDmOJ^azCk{BNNkgxDakv*|Ms00nk^5m!Lm z*BUC1#^=>?r4#uMj!KCn)RykH`cNx7)Jh=4vjJ#Iy<1-LKbgkbXwNzoFY%Y)34FTt zJ-V6_bf~lub8wRGtc3(`A7e8@|Ck|1qB`0v5ifg-SnWQ1InCbw@%MW@8_x3JQ&@Gr z_dO-WZBCj_(+mvyOJkkBp3y7&oU*7r!732DKNOGam!`(QgR7ChF|bjcbCTKdr?2R1 zu$k2{m6fon*)3)K{nsdLy%rO6;wDvRDrs_T0>o@VI( zon&8TAHMq|o3pg0pKr+$e*3HWLZf)*r0{VmLX=jFju3D!?~ZS83cPc$bK*+c&sO75 ztW7~pl!IQI{;|agx!VE7#4ZLPwH6@a2{6{(bzpC>otWU|RPdpLTo9Z0I|{NDpMJ`5 zNmttnzt)i2`D@v}?zCIzN&c)(4zI~=8{qFbNz}q5#h1Jkd#^$o$)FJrHFkeD|DPgi zZeN6^DLKoDenoc^pB0Y6+e_V4LAu2`ubO7t+H^Nn-CzeSh|rW|&JSX|3_V^>LeM@y z{$pJn-zkDDFoJCOpXBu%2v9coHadL0%wQ&17Hxvd&o@_s?g)tKmU(i)lcdehQ~MI; z9CCL>-*DDgYUDf0FJAp_r>P>Fr?-R(xPbl>yhB_8&wHDWST0)VP5q z?>(~29D)qqn9Y-K+c=vPg@(@WZuvU6uS1^|q(l;V5i4#pdC{^6G2KR<_Y9E!K)*~Q z#Qu-D@64ExHxLPLul|LVc6c70gNp?yD=Mz>KC2j|2W?^~xXF=QH2UJsN1S&Vs+U5_ zicfu)?SPY)hLBC9coxf3%vO_^muHr(Ndf-w*-OX7bpE_VUMyt`rnCo?cBesX3}zcG zRIqgUmouyuO6!BRv~)P`=|XY`<|g(;*J-fsdU^%;#ZO0fnsXG8 zELUGNIHOz3aJ(MzHc&$k{Q2eF$hrco&9#jAel$?a24RYAjVI$n%#|@6T94$ULMXy)ys{AYgz6_n8+jnEjFxgm^|Y@OVDaOa45 z#R-8jjtAs>N?E&e7VHBfVG6SZvK|jA%vuZHkd!tt#D@Z>vm#QZA&!%Kp6Tj!yomGHAD97ZRz8Gd)Ax;@@M?+nJAUf4RqU-h#6a`8 z?`b+;q*=*hsbtuYFk!L!M}S<_F>O0MqkppIXT}77j)4UZuebV%%Uwpk?~q+>VXvM? z(=Z56L@2$@89@D0`gAM#mmte<}KrpNYz141UjOhGA1aMN#@s_i-8&V9d7F zcZR8lhj_z}UoCMNf>OBeg*&LaFPKUh{cTaNWtQnka4e73nKk|mS z6QP;xRZh`0|084kLI!~Uj1x<{f`$i+MHX(UNcg&dUEzp@3RT%mhYiS2cgJ2#Zf<4vJA ztqnQz*rLTuxjFq5kTa(>S8SCTiZCRujs(&rKpV(TzoO(MV$j!5*8uTf@Td^x*D#BP zFN^F}=9b+Sr&d!TGV?8@%tGDJ`sz3R9RE5g;AP?S`}_L@`78!(|B=etPtcDSXaO=% z2S7R0q*zHM1H6Zw^l6+6^URPsbtN&38z}y=Fm|BD*Kp8J&EVS+|-mKeOHL>;KuBlY71yk-@!d$pH|1 z(KHDWx}(Kfk1?VtAvx?wA3my

LU)`NQ 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 literal 0 HcmV?d00001 diff --git a/assets/rviewer.png b/assets/rviewer.png new file mode 100644 index 0000000000000000000000000000000000000000..28c4979cd73b875e6e0c418fffabf0bd66ce0689 GIT binary patch literal 34837 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 literal 0 HcmV?d00001 From 10ffb4636b45f2a5d7fbc866dda1e13db3a9c283 Mon Sep 17 00:00:00 2001 From: Lorna Jane Mitchell Date: Wed, 6 Sep 2023 17:06:40 +0100 Subject: [PATCH 26/37] chore: fix header format in gitter example (#965) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fran Méndez --- examples/gitter-streaming.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/gitter-streaming.yml b/examples/gitter-streaming.yml index 444bc9b81..b1dd57b29 100644 --- a/examples/gitter-streaming.yml +++ b/examples/gitter-streaming.yml @@ -160,5 +160,9 @@ components: streamingHeaders: http: headers: - 'Transfer-Encoding': 'chunked' - Trailer: '\r\n' + type: object + properties: + 'Transfer-Encoding': + const: 'chunked' + Trailer: + const: '\r\n' From a4ac4e7d846f08918cbfd4d670b8e20848dbf835 Mon Sep 17 00:00:00 2001 From: Darren Dsouza <130863032+DarrenDsouza7273@users.noreply.github.com> Date: Wed, 27 Sep 2023 22:56:59 +0530 Subject: [PATCH 27/37] chore: add swix as the new silver sponsor (#974) --- README.md | 8 ++++---- assets/swix.png | Bin 0 -> 52944 bytes 2 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 assets/swix.png diff --git a/README.md b/README.md index 3fd000278..f3b7d84b5 100644 --- a/README.md +++ b/README.md @@ -102,10 +102,6 @@ Check out the [examples](https://github.com/asyncapi/asyncapi/blob/master/exampl IBM logo      - - IQVIA logo - -      Postman logo @@ -131,6 +127,10 @@ Check out the [examples](https://github.com/asyncapi/asyncapi/blob/master/exampl Bump.sh logo      + + swix logo + +     

diff --git a/assets/swix.png b/assets/swix.png new file mode 100644 index 0000000000000000000000000000000000000000..88325e9dd97bcce6a7791f81dfd6c50e895a8967 GIT binary patch literal 52944 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

-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%0D%vqyU=GpmgYc1D; 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 literal 0 HcmV?d00001 From d4c99e4971ba67f3c663beb8b0c5b1bd8f8179ff Mon Sep 17 00:00:00 2001 From: Josh Ponelat Date: Wed, 18 Oct 2023 10:11:01 +0200 Subject: [PATCH 28/37] docs: channel object / $ref note. (#826) Co-authored-by: Lukasz Gornicki --- spec/asyncapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/asyncapi.md b/spec/asyncapi.md index 26bbd7f33..e57815747 100644 --- a/spec/asyncapi.md +++ b/spec/asyncapi.md @@ -595,7 +595,7 @@ Describes the operations available on a single channel. Field Name | Type | Description ---|:---:|--- -$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. +$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:** Using the $ref property with other properties is deprecated since the 2.3.0 version of the specification. 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. From 0e1d020a4e99dc5d02282838a9794219103ab843 Mon Sep 17 00:00:00 2001 From: Tabah Baridule M Date: Thu, 26 Oct 2023 09:39:29 +0100 Subject: [PATCH 29/37] docs: add info about breaking changes to contributing guide (#854) Co-authored-by: Sergio Moya <1083296+smoya@users.noreply.github.com>%0ACo-authored-by: Lukasz Gornicki --- CONTRIBUTING.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d096c5f46..8799f4b0b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -78,6 +78,19 @@ move forward. The AsyncAPI spec, despite describing technical behavior, is intended to be read by people. Use natural tone and include motivation and examples. +## Breaking Change vs Non Breaking Change + +Specifications are not much different than software. Some changes provided in the spec can cause breaking changes for tools that support it. For example, if one of the properties that was `required` becomes `optional`, it is considered a breaking change because some tools might depend on that property and fail if it is not provided. + +_Non-breaking changes:_ +- Adding a new optional property + +_Breaking changes:_ +- Adding a new required property +- Making a property required +- Making a property optional +- Removing a property +- Changing the type of a property in backward incompatible way ## RFC Contribution Champions @@ -253,4 +266,4 @@ docker run -v $PWD:/workdir ghcr.io/igorshubovych/markdownlint-cli:v0.35.0 "spec ``` ## References -This document was adapted from the [GraphQL Specification Contribution Guide](https://github.com/graphql/graphql-spec/blob/main/CONTRIBUTING.md). \ No newline at end of file +This document was adapted from the [GraphQL Specification Contribution Guide](https://github.com/graphql/graphql-spec/blob/main/CONTRIBUTING.md). From ced795c583d01fbdf5f7069cc8727277e0b6a329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Gorej?= Date: Fri, 10 Nov 2023 11:39:30 +0100 Subject: [PATCH 30/37] docs: use URL pointing to JSON Schema Draft 7 specs (#982) --- spec/asyncapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/asyncapi.md b/spec/asyncapi.md index e57815747..2b9720418 100644 --- a/spec/asyncapi.md +++ b/spec/asyncapi.md @@ -1702,7 +1702,7 @@ components: #### Schema Object The Schema Object allows the definition of input and output data types. -These types can be objects, but also primitives and arrays. This object is a superset of the [JSON Schema Specification Draft 07](https://json-schema.org/). The empty schema (which allows any instance to validate) MAY be represented by the `boolean` value `true` and a schema which allows no instance to validate MAY be represented by the `boolean` value `false`. +These types can be objects, but also primitives and arrays. This object is a superset of the [JSON Schema Specification Draft 07](https://json-schema.org/specification-links.html#draft-7). The empty schema (which allows any instance to validate) MAY be represented by the `boolean` value `true` and a schema which allows no instance to validate MAY be represented by the `boolean` value `false`. Further information about the properties can be found in [JSON Schema Core](https://tools.ietf.org/html/draft-handrews-json-schema-01) and [JSON Schema Validation](https://tools.ietf.org/html/draft-handrews-json-schema-validation-01). Unless stated otherwise, the property definitions follow the JSON Schema specification as referenced here. From 69ff34dee6c240e41dcc66bd1db6f1c84cf68342 Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Wed, 15 Nov 2023 16:43:04 +0100 Subject: [PATCH 31/37] ci: update of files from global .github repo (#990) --- .github/workflows/automerge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index 9253675cd..116b80652 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -45,7 +45,7 @@ jobs: env: GITHUB_TOKEN: "${{ secrets.GH_TOKEN }}" GITHUB_LOGIN: asyncapi-bot - MERGE_LABELS: "" + MERGE_LABELS: "!do-not-merge" MERGE_METHOD: "squash" MERGE_COMMIT_MESSAGE: "{pullRequest.title} (#{pullRequest.number})" MERGE_RETRIES: "20" From 83fd0b91520111c45098c8cd95d36a37b3250654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Gorej?= Date: Thu, 16 Nov 2023 10:30:52 +0100 Subject: [PATCH 32/37] docs: align text definition of Message.payload with it's field definition (#983) --- spec/asyncapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/asyncapi.md b/spec/asyncapi.md index 2b9720418..3807ef2ba 100644 --- a/spec/asyncapi.md +++ b/spec/asyncapi.md @@ -104,7 +104,7 @@ A consumer is a type of application, connected to a [server](#definitionsServer) ### Message -A message is the mechanism by which information is exchanged via a channel between [servers](#definitionsServer) and applications. A message MUST contain a payload and MAY also contain headers. The headers MAY be subdivided into [protocol](#definitionsProtocol)-defined headers and header properties defined by the application which can act as supporting metadata. The payload contains the data, defined by the application, which MUST be serialized into a format (JSON, XML, Avro, binary, etc.). Since a message is a generic mechanism, it can support multiple interaction patterns such as event, command, request, or response. +A message is the mechanism by which information is exchanged via a channel between [servers](#definitionsServer) and applications. A message MAY contain a payload and MAY also contain headers. The headers MAY be subdivided into [protocol](#definitionsProtocol)-defined headers and header properties defined by the application which can act as supporting metadata. The payload contains the data, defined by the application, which MUST be serialized into a format (JSON, XML, Avro, binary, etc.). Since a message is a generic mechanism, it can support multiple interaction patterns such as event, command, request, or response. ### Channel From ba8ea9dbbf7850740feb995ad6ab8f1d2797bdc2 Mon Sep 17 00:00:00 2001 From: Jonas Lagoni Date: Mon, 4 Dec 2023 11:49:16 -1000 Subject: [PATCH 33/37] chore: apply #853 --- spec/asyncapi.md | 84 ++++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/spec/asyncapi.md b/spec/asyncapi.md index 7533fd494..71e864291 100644 --- a/spec/asyncapi.md +++ b/spec/asyncapi.md @@ -72,48 +72,48 @@ Aside from the issues mentioned above, there may also be infrastructure configur - [Channel](#definitionsChannel) - [Protocol](#definitionsProtocol) - [Specification](#specification) - - [Format](#format) - - [File Structure](#file-structure) - - [Absolute URLs](#absolute-urls) - - [Schema](#schema) - - [AsyncAPI Object](#A2SObject) - - [AsyncAPI Version String](#A2SVersionString) - - [Identifier](#A2SIdString) - - [Info Object](#infoObject) - - [Contact Object](#contactObject) - - [License Object](#licenseObject) - - [Servers Object](#serversObject) - - [Server Object](#serverObject) - - [Server Variable Object](#serverVariableObject) - - [Default Content Type](#defaultContentTypeString) - - [Channels Object](#channelsObject) - - [Channel Object](#channelObject) - - [Operations Object](#operationsObject) - - [Operation Object](#operationObject) - - [Operation Trait Object](#operationTraitObject) - - [Operation Reply Object](#operationReplyObject) - - [Operation Reply Address Object](#operationReplyAddressObject) - - [Message Object](#messageObject) - - [Message Trait Object](#messageTraitObject) - - [Message Example Object](#messageExampleObject) - - [Tags Object](#tagsObject) - - [Tag Object](#tag-object) - - [External Documentation Object](#externalDocumentationObject) - - [Components Object](#componentsObject) - - [Reference Object](#referenceObject) - - [Multi Format Schema Object](#multiFormatSchemaObject) - - [Schema Object](#schemaObject) - - [Security Scheme Object](#securitySchemeObject) - - [OAuth Flows Object](#oauth-flows-object) - - [OAuth Flow Object](#oauth-flow-object) - - [Server Bindings Object](#serverBindingsObject) - - [Parameters Object](#parametersObject) - - [Parameter Object](#parameterObject) - - [Channel Bindings Object](#channelBindingsObject) - - [Operation Bindings Object](#operationBindingsObject) - - [Message Bindings Object](#messageBindingsObject) - - [Correlation ID Object](#correlationIdObject) - - [Specification Extensions](#specificationExtensions) + - [Format](#format) + - [File Structure](#file-structure) + - [Absolute URLs](#absolute-urls) + - [Schema](#schema) + - [AsyncAPI Object](#A2SObject) + - [AsyncAPI Version String](#A2SVersionString) + - [Identifier](#A2SIdString) + - [Info Object](#infoObject) + - [Contact Object](#contactObject) + - [License Object](#licenseObject) + - [Servers Object](#serversObject) + - [Server Object](#serverObject) + - [Server Variable Object](#serverVariableObject) + - [Default Content Type](#defaultContentTypeString) + - [Channels Object](#channelsObject) + - [Channel Object](#channelObject) + - [Operations Object](#operationsObject) + - [Operation Object](#operationObject) + - [Operation Trait Object](#operationTraitObject) + - [Operation Reply Object](#operationReplyObject) + - [Operation Reply Address Object](#operationReplyAddressObject) + - [Message Object](#messageObject) + - [Message Trait Object](#messageTraitObject) + - [Message Example Object](#messageExampleObject) + - [Tags Object](#tagsObject) + - [Tag Object](#tag-object) + - [External Documentation Object](#externalDocumentationObject) + - [Components Object](#componentsObject) + - [Reference Object](#referenceObject) + - [Multi Format Schema Object](#multiFormatSchemaObject) + - [Schema Object](#schemaObject) + - [Security Scheme Object](#securitySchemeObject) + - [OAuth Flows Object](#oauth-flows-object) + - [OAuth Flow Object](#oauth-flow-object) + - [Server Bindings Object](#serverBindingsObject) + - [Parameters Object](#parametersObject) + - [Parameter Object](#parameterObject) + - [Channel Bindings Object](#channelBindingsObject) + - [Operation Bindings Object](#operationBindingsObject) + - [Message Bindings Object](#messageBindingsObject) + - [Correlation ID Object](#correlationIdObject) + - [Specification Extensions](#specificationExtensions) From 297b33618776210d605972943d3055b0b29f3fa0 Mon Sep 17 00:00:00 2001 From: Jonas Lagoni Date: Mon, 4 Dec 2023 11:49:31 -1000 Subject: [PATCH 34/37] chore: apply #884 --- examples/websocket-gemini-asyncapi.yml | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/examples/websocket-gemini-asyncapi.yml b/examples/websocket-gemini-asyncapi.yml index 675640f34..7abcba981 100644 --- a/examples/websocket-gemini-asyncapi.yml +++ b/examples/websocket-gemini-asyncapi.yml @@ -180,9 +180,9 @@ components: events: - type: change side: bid - price: '54350.40' - remaining: '0.002' - delta: '0.002' + price: 54350.40 + remaining: 0.002 + delta: 0.002 reason: place - name: heartbeatMessage summary: Example of additional heartbeat message when you enable them. @@ -219,15 +219,13 @@ components: events: $ref: '#/components/schemas/events' timestamp: - type: string - format: date-time + type: number description: >- The timestamp in seconds for this group of events (included for compatibility reasons). We recommend using the timestampms field instead. timestampms: - type: string - format: time + type: number description: The timestamp in milliseconds for this group of events. required: - type @@ -272,7 +270,7 @@ components: - 'auction, block_trade' price: type: number - multipleOf: 1 + multipleOf: 0.01 description: The price of this order book entry. side: type: string @@ -292,14 +290,12 @@ components: order book. remaining: type: number - multipleOf: 1 description: >- The quantity remaining at that price level after this change occurred. May be zero if all orders at this price level have been filled or canceled. delta: type: number - multipleOf: 1 description: >- The quantity changed. May be negative, if an order is filled or canceled. For initial messages, delta will equal remaining. \ No newline at end of file From 3cb55502f1ee9bf1708c0e02464bd41363353de7 Mon Sep 17 00:00:00 2001 From: Jonas Lagoni Date: Mon, 4 Dec 2023 11:53:03 -1000 Subject: [PATCH 35/37] chore: apply #902 --- spec/asyncapi.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spec/asyncapi.md b/spec/asyncapi.md index 71e864291..1513bfe0f 100644 --- a/spec/asyncapi.md +++ b/spec/asyncapi.md @@ -138,7 +138,7 @@ A message is the mechanism by which information is exchanged via a channel betwe A channel is an addressable component, made available by the [server](#definitionsServer), for the organization of [messages](#definitionsMessage). [Sender](#definitionsSender) applications send messages to channels and [receiver](#definitionsReceiver) applications receive messages from channels. [Servers](#definitionsServer) MAY support many channel instances, allowing messages with different content to be addressed to different channels. Depending on the [server](#definitionsServer) implementation, the channel MAY be included in the message via protocol-defined headers. ### Protocol -A protocol is the mechanism (wireline protocol or API) by which [messages](#definitionsMessage) are exchanged between the application and the [channel](#definitionsChannel). Example protocols include, but are not limited to, AMQP, HTTP, JMS, Kafka, Anypoint MQ, MQTT, Solace, STOMP, Mercure, WebSocket. +A protocol is the mechanism (wireline protocol or API) by which [messages](#definitionsMessage) are exchanged between the application and the [channel](#definitionsChannel). Example protocols include, but are not limited to, AMQP, HTTP, JMS, Kafka, Anypoint MQ, MQTT, Solace, STOMP, Mercure, WebSocket, Google Pub/Sub, Pulsar. ### Bindings A "binding" (or "protocol binding") is a mechanism to define protocol-specific information. Therefore, a protocol binding MUST define protocol-specific information only. @@ -1112,6 +1112,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. `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. +`pulsar` | [Pulsar Server Binding](https://github.com/asyncapi/bindings/tree/master/pulsar#server-binding-object) | Protocol-specific information for a Pulsar server. This object MAY be extended with [Specification Extensions](#specificationExtensions). @@ -1143,6 +1144,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. `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. +`pulsar` | [Pulsar Channel Binding](https://github.com/asyncapi/bindings/tree/master/pulsar#channel-binding-object) | Protocol-specific information for a Pulsar channel. This object MAY be extended with [Specification Extensions](#specificationExtensions). @@ -1174,6 +1176,7 @@ Field Name | Type | Description `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. +`pulsar` | [Pulsar Operation Binding](https://github.com/asyncapi/bindings/tree/master/pulsar#operation-binding-fields) | Protocol-specific information for a Pulsar operation. This object MAY be extended with [Specification Extensions](#specificationExtensions). @@ -1206,6 +1209,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. `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. +`pulsar` | [Pulsar Message Binding](https://github.com/asyncapi/bindings/tree/master/pulsar#message-binding-fields) | Protocol-specific information for a Pulsar message. This object MAY be extended with [Specification Extensions](#specificationExtensions). From 736b5e1c372dc80bc18aa7ddad8947a04387ac40 Mon Sep 17 00:00:00 2001 From: Jonas Lagoni Date: Mon, 4 Dec 2023 11:53:33 -1000 Subject: [PATCH 36/37] chore: apply #909 --- spec/asyncapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/asyncapi.md b/spec/asyncapi.md index 1513bfe0f..7450d3df6 100644 --- a/spec/asyncapi.md +++ b/spec/asyncapi.md @@ -1943,7 +1943,7 @@ While composition offers model extensibility, it does not imply a hierarchy betw To support polymorphism, AsyncAPI Specification adds the support of the `discriminator` field. When used, the `discriminator` will be the name of the property used to decide which schema definition is used to validate the structure of the model. As such, the `discriminator` field MUST be a required field. -There are are two ways to define the value of a discriminator for an inheriting instance. +There are two ways to define the value of a discriminator for an inheriting instance. - Use the schema's name. - Override the schema's name by overriding the property with a new value. If exists, this takes precedence over the schema's name. From 41686ae9b6da349b4aee93ce925f8eb8a7f1ad4a Mon Sep 17 00:00:00 2001 From: Jonas Lagoni Date: Mon, 4 Dec 2023 11:56:49 -1000 Subject: [PATCH 37/37] chore: apply #983 --- spec/asyncapi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/asyncapi.md b/spec/asyncapi.md index 7450d3df6..15d51f22a 100644 --- a/spec/asyncapi.md +++ b/spec/asyncapi.md @@ -132,7 +132,7 @@ A sender is a type of application, that is sending [messages](#definitionsMessag A receiver is a type of application that is receiving [messages](#definitionsMessage) from [channels](#definitionsChannel). A receiver MAY receive from multiple channels depending on the [server](#definitionsServer), protocol, and the use-case pattern. A receiver MAY forward a received message further without changing it. A receiver MAY act as a consumer and react to the message. A receiver MAY act as a processor that, for example, aggregates multiple messages in one and forwards them. ### Message -A message is the mechanism by which information is exchanged via a channel between [servers](#definitionsServer) and applications. A message MUST contain a payload and MAY also contain headers. The headers MAY be subdivided into [protocol](#definitionsProtocol)-defined headers and header properties defined by the application which can act as supporting metadata. The payload contains the data, defined by the application, which MUST be serialized into a format (JSON, XML, Avro, binary, etc.). Since a message is a generic mechanism, it can support multiple interaction patterns such as event, command, request, or response. +A message is the mechanism by which information is exchanged via a channel between [servers](#definitionsServer) and applications. A message MAY contain a payload and MAY also contain headers. The headers MAY be subdivided into [protocol](#definitionsProtocol)-defined headers and header properties defined by the application which can act as supporting metadata. The payload contains the data, defined by the application, which MUST be serialized into a format (JSON, XML, Avro, binary, etc.). Since a message is a generic mechanism, it can support multiple interaction patterns such as event, command, request, or response. ### Channel A channel is an addressable component, made available by the [server](#definitionsServer), for the organization of [messages](#definitionsMessage). [Sender](#definitionsSender) applications send messages to channels and [receiver](#definitionsReceiver) applications receive messages from channels. [Servers](#definitionsServer) MAY support many channel instances, allowing messages with different content to be addressed to different channels. Depending on the [server](#definitionsServer) implementation, the channel MAY be included in the message via protocol-defined headers.