diff --git a/.github/workflows/test-action.yml b/.github/workflows/test-action.yml new file mode 100644 index 00000000000..49960223be7 --- /dev/null +++ b/.github/workflows/test-action.yml @@ -0,0 +1,345 @@ +name: PR testing of CLI action + +on: + pull_request: + types: [ opened, synchronize, reopened, ready_for_review ] + +jobs: + should-workflow-run: + runs-on: ubuntu-latest + steps: + - if: > + !github.event.pull_request.draft && !( + (github.actor == 'asyncapi-bot' && ( + startsWith(github.event.pull_request.title, 'ci: update of files from global .github repo') || + startsWith(github.event.pull_request.title, 'chore(release):') + )) || + (github.actor == 'asyncapi-bot-eve' && ( + startsWith(github.event.pull_request.title, 'ci: update of files from global .github repo') || + startsWith(github.event.pull_request.title, 'chore(release):') + )) || + (github.actor == 'allcontributors[bot]' && + startsWith(github.event.pull_request.title, 'docs: add') + ) + ) + id: should_run + name: Should Run + run: echo "shouldrun=true" >> $GITHUB_OUTPUT + outputs: + shouldrun: ${{ steps.should_run.outputs.shouldrun }} + + build-docker: + needs: should-workflow-run + name: Build Docker image + if: ${{ needs.should-workflow-run.outputs.shouldrun == 'true' }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Get docker version + id: docker_version + run: > + ls -la; + action=$(cat action.yml); + regex='docker:\/\/asyncapi\/github-action-for-cli:([0-9.]+)'; + [[ $action =~ $regex ]]; + action_version=${BASH_REMATCH[1]}; + echo "action_version=$action_version" >> $GITHUB_OUTPUT + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Build Docker image and export + uses: docker/build-push-action@v5 + with: + context: . + file: ./github-action/Dockerfile + tags: asyncapi/github-action-for-cli:${{ steps.docker_version.outputs.action_version }} + outputs: type=docker,dest=/tmp/asyncapi.tar + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: asyncapi + path: /tmp/asyncapi.tar + + + test-defaults: + if: ${{ needs.should-workflow-run.outputs.shouldrun == 'true' }} + runs-on: ubuntu-latest + needs: [should-workflow-run, build-docker] + steps: + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: asyncapi + path: /tmp + - name: Load Docker image + run: | + docker load --input /tmp/asyncapi.tar + docker image ls -a + - uses: actions/checkout@v4 + - name: Test GitHub Action + uses: ./ + with: + filepath: ./github-action/test/asyncapi.yml + - name: Assert GitHub Action + run: | + echo "Listing all files" + ls -R + echo "Asserting GitHub Action" + if [ -f "./output/asyncapi.md" ]; then + echo "Files exist" + else + echo "Files do not exist:- ./output/asyncapi.md" + echo "Action failed" + exit 1 + fi + + test-validate-success: + if: ${{ needs.should-workflow-run.outputs.shouldrun == 'true' }} + runs-on: ubuntu-latest + needs: [should-workflow-run, build-docker] + steps: + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: asyncapi + path: /tmp + - name: Load Docker image + run: | + docker load --input /tmp/asyncapi.tar + docker image ls -a + - uses: actions/checkout@v4 + - name: Test GitHub Action + uses: ./ + with: + filepath: ./github-action/test/asyncapi.yml + command: validate + + test-custom-command: + if: ${{ needs.should-workflow-run.outputs.shouldrun == 'true' }} + runs-on: ubuntu-latest + needs: [should-workflow-run, build-docker] + steps: + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: asyncapi + path: /tmp + - name: Load Docker image + run: | + docker load --input /tmp/asyncapi.tar + docker image ls -a + - uses: actions/checkout@v4 + - name: Test GitHub Action + uses: ./ + with: + # Custom command to generate models + # Note: You can use command itself to generate models, but this is just an example for testing custom commands + custom_command: "generate models typescript ./github-action/test/asyncapi.yml -o ./output" + - name: Assert GitHub Action + run: | + echo "Listing all files" + ls -R + echo "Asserting GitHub Action" + if [ -f "./output/AnonymousSchema_1.ts" ]; then + echo "Models have been generated" + else + echo "Models have not been generated" + echo "Action failed" + exit 1 + fi + + test-custom-output: + if: ${{ needs.should-workflow-run.outputs.shouldrun == 'true' }} + runs-on: ubuntu-latest + needs: [should-workflow-run, build-docker] + steps: + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: asyncapi + path: /tmp + - name: Load Docker image + run: | + docker load --input /tmp/asyncapi.tar + docker image ls -a + - uses: actions/checkout@v4 + - name: Test GitHub Action + uses: ./ + with: + filepath: ./github-action/test/asyncapi.yml + output: custom-output + - name: Assert GitHub Action + run: | + echo "Listing all files" + ls -R + echo "Asserting GitHub Action" + if [ -f "./custom-output/asyncapi.md" ]; then + echo "Files exist" + else + echo "Files do not exist:- ./custom-output/asyncapi.md" + echo "Action failed" + exit 1 + fi + + test-file-not-found: + if: ${{ needs.should-workflow-run.outputs.shouldrun == 'true' }} + runs-on: ubuntu-latest + needs: [should-workflow-run, build-docker] + steps: + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: asyncapi + path: /tmp + - name: Load Docker image + run: | + docker load --input /tmp/asyncapi.tar + docker image ls -a + - uses: actions/checkout@v4 + - name: Test GitHub Action + id: test + uses: ./ + with: + filepath: non_existent_file.yml + continue-on-error: true + - name: Check for failure + run: | + if [ "${{ steps.test.outcome }}" == "success" ]; then + echo "Test Failure: non_existent_file.yml should throw an error but did not" + exit 1 + else + echo "Test Success: non_existent_file.yml threw an error as expected" + fi + + test-invalid-input: + if: ${{ needs.should-workflow-run.outputs.shouldrun == 'true' }} + runs-on: ubuntu-latest + needs: [should-workflow-run, build-docker] + steps: + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: asyncapi + path: /tmp + - name: Load Docker image + run: | + docker load --input /tmp/asyncapi.tar + docker image ls -a + - uses: actions/checkout@v4 + - name: Test GitHub Action + id: test + uses: ./ + with: + filepath: github-action/test/asyncapi.yml + command: generate # No template or language specified + template: '' # Empty string + continue-on-error: true + - name: Check for failure + run: | + if [ "${{ steps.test.outcome }}" == "success" ]; then + echo "Test Failure: generate command should throw an error as no template or language specified but did not" + exit 1 + else + echo "Test Success: generate command threw an error as expected" + fi + + test-optimize: + if: ${{ needs.should-workflow-run.outputs.shouldrun == 'true' }} + runs-on: ubuntu-latest + needs: [should-workflow-run, build-docker] + steps: + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: asyncapi + path: /tmp + - name: Load Docker image + run: | + docker load --input /tmp/asyncapi.tar + docker image ls -a + - uses: actions/checkout@v4 + - name: Test GitHub Action + uses: ./ + with: + filepath: github-action/test/unoptimized.yml + command: optimize + parameters: '-o new-file --no-tty' + - name: Assert GitHub Action + run: | + echo "Listing all files" + ls -R + echo "Asserting GitHub Action" + if [ -f "./github-action/test/unoptimized_optimized.yml" ]; then + echo "The specified file has been optimized" + else + echo "The specified file has not been optimized" + echo "Action failed" + exit 1 + fi + + test-bundle: + if: ${{ needs.should-workflow-run.outputs.shouldrun == 'true' }} + runs-on: ubuntu-latest + needs: [should-workflow-run, build-docker] + steps: + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: asyncapi + path: /tmp + - name: Load Docker image + run: | + docker load --input /tmp/asyncapi.tar + docker image ls -a + - uses: actions/checkout@v4 + - name: Make output directory + run: mkdir -p ./output/bundle + - name: Test GitHub Action + uses: ./ + with: + custom_command: 'bundle ./github-action/test/bundle/asyncapi.yaml ./github-action/test/bundle/features.yaml --base ./github-action/test/bundle/asyncapi.yaml -o ./output/bundle/asyncapi.yaml' + - name: Assert GitHub Action + run: | + echo "Listing all files" + ls -R + echo "Asserting GitHub Action" + if [ -f "./output/bundle/asyncapi.yaml" ]; then + echo "The specified files have been bundled" + else + echo "The specified files have not been bundled" + echo "Action failed" + exit 1 + fi + + test-convert: + if: ${{ needs.should-workflow-run.outputs.shouldrun == 'true' }} + runs-on: ubuntu-latest + needs: [should-workflow-run, build-docker] + steps: + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: asyncapi + path: /tmp + - name: Load Docker image + run: | + docker load --input /tmp/asyncapi.tar + docker image ls -a + - uses: actions/checkout@v4 + - name: Test GitHub Action + uses: ./ + with: + command: convert + filepath: github-action/test/asyncapi.yml + output: output/convert/asyncapi.yaml + - name: Assert GitHub Action + run: | + echo "Listing all files" + ls -R + echo "Asserting GitHub Action" + if [ -f "./output/convert/asyncapi.yaml" ]; then + echo "The specified file has been converted" + else + echo "The specified file has not been converted" + echo "Action failed" + exit 1 + fi diff --git a/.github/workflows/upload-release-assets.yml b/.github/workflows/upload-release-assets.yml index e0018e4b0b9..f9c979955ad 100644 --- a/.github/workflows/upload-release-assets.yml +++ b/.github/workflows/upload-release-assets.yml @@ -50,6 +50,11 @@ jobs: uses: actions/setup-node@v4 with: node-version: "${{ steps.lockversion.outputs.version }}" + - if: matrix.npm_script == 'pack:windows' + name: install nodejs for windows + uses: actions/setup-node@v4 + with: + node-version: 20 - name: Get version from package.json uses: actions/github-script@v6 id: extractver @@ -62,11 +67,12 @@ jobs: #fix for windows build issue #1433 name: Install p7zip-full nsis run: sudo apt-get install -y p7zip-full nsis - - if: steps.lockversion.outputs.version == '18' && matrix.os == 'windows-latest' + + - if: matrix.npm_script == 'pack:windows' #npm cli 10 is buggy because of some cache issue - name: Install npm cli 8 + name: Install npm cli 10 shell: bash - run: npm install -g npm@8.19.4 + run: npm install -g npm@latest - name: Install dependencies run: npm ci - name: Build project diff --git a/.gitignore b/.gitignore index b50ab0c5d88..5b8a7c8b336 100644 --- a/.gitignore +++ b/.gitignore @@ -16,10 +16,12 @@ node_modules /test/integration/generate/models/ test.asyncapi-cli asyncapi.json -asyncapi.yml test/fixtures/minimaltemplate/__transpiled .vscode +/action/ +/github-action/output/ + oclif.manifest.json spec-examples.zip diff --git a/action.yml b/action.yml new file mode 100644 index 00000000000..5366e43d079 --- /dev/null +++ b/action.yml @@ -0,0 +1,54 @@ +name: 'Generator, Validator, Converter and others - all in one for your AsyncAPI docs' +description: 'Use this action to generate docs or code from your AsyncAPI document. Use default templates or provide your custom ones.' +inputs: + cli_version: + description: 'Version of AsyncAPI CLI to be used. This is only needed if you want to test with a specific version of AsyncAPI CLI. Default is latest which is also the recommended option.' + required: false + default: '' + command: + description: 'Command to run. Available commands in action :- generate, validate, convert, optimize and custom. Default is generate. For custom command, provide the whole command as input. List of available commands can be found in https://www.asyncapi.com/docs/tools/cli/usage.' + required: false + default: 'generate' + filepath: + description: 'Path to AsyncAPI document. This input is required if command is set to generate, validate, convert or optimize. Default is ./asyncapi.yaml' + required: false + default: 'asyncapi.yml' + template: + description: 'Template for the generator. Official templates are listed here https://github.com/search?q=topic%3Aasyncapi+topic%3Agenerator+topic%3Atemplate. You can pass template as npm package, url to git repository, link to tar file or local template.' + default: '@asyncapi/markdown-template@0.10.0' + required: false + language: + description: 'Language of the generated code. This input is required if you want to generate models. List of available languages can be found in https://www.asyncapi.com/docs/tools/cli/usage#asyncapi-generate-models-language-file' + required: false + default: '' + output: + description: 'Directory where to put the generated files. Can be used only with generate or convert commands. Default is output.' + required: false + default: 'output' + parameters: + description: 'The command that you use might support and even require specific parameters to be passed to the CLI for the generation. Template parameters should be preceded by -p' + required: false + default: '' + custom_command: + description: 'Custom command to be run. This input is required if command is set to custom.' + required: false + default: '' + +runs: + using: 'docker' + # This is the image that will be used to run the action. + # IMPORTANT: The version has to be changed manually in your PRs. + image: 'docker://asyncapi/github-action-for-cli:3.1.2' + args: + - ${{ inputs.cli_version }} + - ${{ inputs.command }} + - ${{ inputs.filepath }} + - ${{ inputs.template }} + - ${{ inputs.language }} + - ${{ inputs.output }} + - ${{ inputs.parameters }} + - ${{ inputs.custom_command }} + +branding: + icon: 'file-text' + color: purple diff --git a/docs/usage.md b/docs/usage.md index 3a1ddf96022..a8d86b446bc 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -27,7 +27,7 @@ $ npm install -g @asyncapi/cli $ asyncapi COMMAND running command... $ asyncapi (--version) -@asyncapi/cli/2.4.1 linux-x64 node-v18.20.4 +@asyncapi/cli/2.7.3 linux-x64 node-v18.20.4 $ asyncapi --help [COMMAND] USAGE $ asyncapi COMMAND @@ -99,7 +99,7 @@ EXAMPLES $ asyncapi bundle ./asyncapi.yaml -o final-asyncapi.yaml --base ../public-api/main.yaml --baseDir ./social-media/comments-service ``` -_See code: [src/commands/bundle.ts](https://github.com/asyncapi/cli/blob/v2.4.1/src/commands/bundle.ts)_ +_See code: [src/commands/bundle.ts](https://github.com/asyncapi/cli/blob/v2.7.3/src/commands/bundle.ts)_ ## `asyncapi config` @@ -113,7 +113,7 @@ DESCRIPTION CLI config settings ``` -_See code: [src/commands/config/index.ts](https://github.com/asyncapi/cli/blob/v2.4.1/src/commands/config/index.ts)_ +_See code: [src/commands/config/index.ts](https://github.com/asyncapi/cli/blob/v2.7.3/src/commands/config/index.ts)_ ## `asyncapi config analytics` @@ -133,7 +133,7 @@ DESCRIPTION Enable or disable analytics for metrics collection ``` -_See code: [src/commands/config/analytics.ts](https://github.com/asyncapi/cli/blob/v2.4.1/src/commands/config/analytics.ts)_ +_See code: [src/commands/config/analytics.ts](https://github.com/asyncapi/cli/blob/v2.7.3/src/commands/config/analytics.ts)_ ## `asyncapi config context` @@ -147,7 +147,7 @@ DESCRIPTION Manage short aliases for full paths to AsyncAPI documents ``` -_See code: [src/commands/config/context/index.ts](https://github.com/asyncapi/cli/blob/v2.4.1/src/commands/config/context/index.ts)_ +_See code: [src/commands/config/context/index.ts](https://github.com/asyncapi/cli/blob/v2.7.3/src/commands/config/context/index.ts)_ ## `asyncapi config context add CONTEXT-NAME SPEC-FILE-PATH` @@ -169,7 +169,7 @@ DESCRIPTION Add a context to the store ``` -_See code: [src/commands/config/context/add.ts](https://github.com/asyncapi/cli/blob/v2.4.1/src/commands/config/context/add.ts)_ +_See code: [src/commands/config/context/add.ts](https://github.com/asyncapi/cli/blob/v2.7.3/src/commands/config/context/add.ts)_ ## `asyncapi config context current` @@ -186,7 +186,7 @@ DESCRIPTION Shows the current context that is being used ``` -_See code: [src/commands/config/context/current.ts](https://github.com/asyncapi/cli/blob/v2.4.1/src/commands/config/context/current.ts)_ +_See code: [src/commands/config/context/current.ts](https://github.com/asyncapi/cli/blob/v2.7.3/src/commands/config/context/current.ts)_ ## `asyncapi config context edit CONTEXT-NAME NEW-SPEC-FILE-PATH` @@ -207,7 +207,7 @@ DESCRIPTION Edit a context in the store ``` -_See code: [src/commands/config/context/edit.ts](https://github.com/asyncapi/cli/blob/v2.4.1/src/commands/config/context/edit.ts)_ +_See code: [src/commands/config/context/edit.ts](https://github.com/asyncapi/cli/blob/v2.7.3/src/commands/config/context/edit.ts)_ ## `asyncapi config context init [CONTEXT-FILE-PATH]` @@ -230,7 +230,7 @@ DESCRIPTION Initialize context ``` -_See code: [src/commands/config/context/init.ts](https://github.com/asyncapi/cli/blob/v2.4.1/src/commands/config/context/init.ts)_ +_See code: [src/commands/config/context/init.ts](https://github.com/asyncapi/cli/blob/v2.7.3/src/commands/config/context/init.ts)_ ## `asyncapi config context list` @@ -247,7 +247,7 @@ DESCRIPTION List all the stored contexts in the store ``` -_See code: [src/commands/config/context/list.ts](https://github.com/asyncapi/cli/blob/v2.4.1/src/commands/config/context/list.ts)_ +_See code: [src/commands/config/context/list.ts](https://github.com/asyncapi/cli/blob/v2.7.3/src/commands/config/context/list.ts)_ ## `asyncapi config context remove CONTEXT-NAME` @@ -267,7 +267,7 @@ DESCRIPTION Delete a context from the store ``` -_See code: [src/commands/config/context/remove.ts](https://github.com/asyncapi/cli/blob/v2.4.1/src/commands/config/context/remove.ts)_ +_See code: [src/commands/config/context/remove.ts](https://github.com/asyncapi/cli/blob/v2.7.3/src/commands/config/context/remove.ts)_ ## `asyncapi config context use CONTEXT-NAME` @@ -287,7 +287,7 @@ DESCRIPTION Set a context as current ``` -_See code: [src/commands/config/context/use.ts](https://github.com/asyncapi/cli/blob/v2.4.1/src/commands/config/context/use.ts)_ +_See code: [src/commands/config/context/use.ts](https://github.com/asyncapi/cli/blob/v2.7.3/src/commands/config/context/use.ts)_ ## `asyncapi config versions` @@ -304,22 +304,23 @@ DESCRIPTION Show versions of AsyncAPI tools used ``` -_See code: [src/commands/config/versions.ts](https://github.com/asyncapi/cli/blob/v2.4.1/src/commands/config/versions.ts)_ +_See code: [src/commands/config/versions.ts](https://github.com/asyncapi/cli/blob/v2.7.3/src/commands/config/versions.ts)_ ## `asyncapi convert [SPEC-FILE]` -Convert asyncapi documents older to newer versions or OpenAPI documents to AsyncAPI +Convert asyncapi documents older to newer versions or OpenAPI/postman-collection documents to AsyncAPI ``` USAGE - $ asyncapi convert [SPEC-FILE] -f openapi|asyncapi [-h] [-o ] [-t ] [-p client|server] + $ asyncapi convert [SPEC-FILE] -f openapi|asyncapi|postman-collection [-h] [-o ] [-t ] [-p + client|server] ARGUMENTS SPEC-FILE spec path, url, or context-name FLAGS -f, --format=