diff --git a/.github/actionconfig.go b/.github/actionconfig.go index 199048de..ab9a4663 100644 --- a/.github/actionconfig.go +++ b/.github/actionconfig.go @@ -15,7 +15,6 @@ const ( publishIdentifier = "publish_" inputConfigKey = "inputs" securityConfigKey = "secrets" - createRelease = "create_release" schemaTokenKey = "openapi_doc_auth_token" ) @@ -42,7 +41,7 @@ func GenerateActionInputsConfig() (*SDKGenConfig, error) { } for _, inputConfigField := range inputConfigFields { - if strings.Contains(inputConfigField.Name, publishIdentifier) || inputConfigField.Name == createRelease { + if strings.Contains(inputConfigField.Name, publishIdentifier) { reqForPublishing := true inputConfigField.RequiredForPublishing = &reqForPublishing if inputConfigField.Language != nil && *inputConfigField.Language != "" { diff --git a/.github/workflows/sdk-generation.yaml b/.github/workflows/sdk-generation.yaml index fda9bfbc..e69de29b 100644 --- a/.github/workflows/sdk-generation.yaml +++ b/.github/workflows/sdk-generation.yaml @@ -1,1270 +0,0 @@ -name: Speakeasy SDK Generation Workflow - -on: - workflow_call: - inputs: - speakeasy_version: - description: The version of the Speakeasy CLI to use or "latest" - default: latest - required: false - type: string - openapi_doc_location: - description: The location of the OpenAPI document to use, either a relative path within the repo or a URL to a publicly hosted document - required: false - type: string - openapi_doc_auth_header: - description: |- - The auth header to use when fetching the OpenAPI document if it is not publicly hosted. For example `Authorization`. - If using a private speakeasy hosted document use `x-api-key`. This header will be populated with the openapi_doc_auth_token provided. - required: false - type: string - openapi_docs: - description: |- - A yaml string containing a list of OpenAPI documents to use, if multiple documents are provided they will be merged together, prior to generation. - - If the document lives within the repo a relative path can be provided, if the document is hosted publicly a URL can be provided. - - If the documents are hosted privately a URL can be provided along with the `openapi_doc_auth_header` and `openapi_doc_auth_token` inputs. - Each document will be fetched using the provided auth header and token, so they need to be valid for all documents. - - For example: - openapi_docs: | - - https://example.com/openapi1.json - - https://example.com/openapi2.json - required: false - type: string - overlay_docs: - description: |- - A yaml string containing a list of overlay documents to use, if multiple documents are provided they will be applied to the OpenAPI document in the order provided. - - If the document lives within the repo a relative path can be provided, if the document is hosted publicly a URL can be provided. - - If the documents are hosted privately a URL can be provided along with the `openapi_doc_auth_header` and `openapi_doc_auth_token` inputs. - Each document will be fetched using the provided auth header and token, so they need to be valid for all documents. - - For example: - overlay_docs: | - - https://example.com/overlay1.json - - https://example.com/overlay2.json - required: false - type: string - languages: - description: |- - A yaml string containing a list of languages to generate SDKs for example: - languages: | - - go: ./go-sdk # specifying a output directory - - python # using default output of ./python-client-sdk - - typescript # using default output of ./typescript-client-sdk - - java # using default output of ./java-client-sdk - - php # using default output of ./php-client-sdk - - csharp # using default output of ./csharp-client-sdk - - swift # using default output of ./swift-client-sdk - - unity # using default output of ./unity-client-sdk - - terraform # (single language repo only) - - If multiple languages are present we will treat this repo as a mono repo, if a single language is present as a single language repo - required: true - type: string - docs_languages: - description: |- - A yaml string containing a list of languages to generate SDK docs for example: - languages: | - - go - - python - - typescript - - java - - csharp - - unity - - curl - required: false - type: string - create_release: - description: "Create a Github release on generation if using 'direct' mode or prepare a release if using 'pr' mode" - default: "true" - required: false - type: string - publish_python: - description: "Publish the Python SDK to PyPi if using 'direct' mode or prepare a release if using 'pr' mode" - default: "false" - required: false - type: string - publish_typescript: - description: "Publish the Typescript SDK to NPM if using 'direct' mode or prepare a release if using 'pr' mode" - default: "false" - required: false - type: string - publish_terraform: - description: "Create a Github release compatible with the terraform registry of the provider" - default: "false" - required: false - type: string - publish_java: - description: "Publish the Java SDK to the OSSRH URL configured in gen.yml if using 'direct' mode or prepare a release if using 'pr' mode" - default: "false" - required: false - type: string - use_sonatype_central: - description: "When publishing the Java SDK, use the Sonatype central portal" - default: "false" - required: false - type: string - publish_php: - description: "Publish the PHP SDK for Composer if using 'direct' mode or prepare a release if using 'pr' mode" - default: "false" - required: false - type: string - publish_ruby: - description: "Publish the Ruby SDK for RubyGems if using 'direct' mode or prepare a release if using 'pr' mode" - default: "false" - required: false - type: string - publish_csharp: - description: "Publish the C# SDK for Nuget if using 'direct' mode or prepare a release if using 'pr' mode" - default: "false" - required: false - type: string - mode: - description: |- - The mode to run the workflow in, valid options are 'direct' or 'pr', defaults to 'direct'. - - 'direct' will create a commit with the changes to the SDKs and push them directly to the branch the workflow is configure to run on (normally 'main' or 'master'). - If publishing and creating a release are configured this will happen immediately after the commit is created on the branch. - - 'pr' will instead create a new branch to commit the changes to the SDKs to and then create a PR from this branch. - The sdk-publish workflow will then need to be configured to run when the PR is merged to publish the SDKs and create a release. - See documentation for more details. - default: "direct" - required: false - type: string - force: - description: "Force the generation of the SDKs" - default: "false" - required: false - type: string - output_tests: - required: false - description: "Internal use only" - default: "false" - type: string - speakeasy_server_url: - required: false - description: "Internal use only" - type: string - working_directory: - description: "The working directory for running Speakeasy CLI commands in the action" - required: false - type: string - dotnet_version: - description: "The version of dotnet to use when compiling the C# SDK" - required: false - type: string - default: "5.x" - secrets: - github_access_token: - description: A GitHub access token with write access to the repo - required: true - pypi_token: - description: A PyPi access token for publishing the package to PyPi, include the `pypi-` prefix - required: false - npm_token: - description: An NPM access token for publishing the package to NPM, include the `npm_` prefix - required: false - packagist_username: - description: A Packagist username for publishing the package to Packagist - required: false - packagist_token: - description: A Packagist API token for publishing the package to Packagist - required: false - openapi_doc_auth_token: - description: The auth token to use when fetching the OpenAPI document if it is not publicly hosted. For example `Bearer ` or ``. - required: false - speakeasy_api_key: - description: The API key to use to authenticate the Speakeasy CLI - required: true - ossrh_username: - description: A username for publishing the Java package to the OSSRH URL provided in gen.yml - required: false - ossrh_password: - description: The corresponding password for publishing the Java package to the OSSRH URL provided in gen.yml - required: false - java_gpg_secret_key: - description: The GPG secret key to use for signing the Java package - required: false - java_gpg_passphrase: - description: The passphrase for the GPG secret key - required: false - slack_webhook_url: - description: A Slack webhook URL that pipeline failures will be posted to - required: false - terraform_gpg_secret_key: - description: The GPG secret key to use for signing the Terraform provider - required: false - terraform_gpg_passphrase: - description: The passphrase for the Terraform GPG secret key - required: false - rubygems_auth_token: - description: The auth token (api key) for publishing to RubyGems - required: false - nuget_api_key: - description: The api key for publishing to the Nuget registry - required: false -jobs: - validate: - name: Validate OpenAPI Document - runs-on: ubuntu-latest - outputs: - resolved_speakeasy_version: ${{ steps.validate.outputs.resolved_speakeasy_version }} - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - id: validate - uses: speakeasy-api/sdk-generation-action@v14 - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - openapi_doc_location: ${{ inputs.openapi_doc_location }} - openapi_doc_auth_header: ${{ inputs.openapi_doc_auth_header }} - openapi_doc_auth_token: ${{ secrets.openapi_doc_auth_token }} - openapi_docs: ${{ inputs.openapi_docs }} - overlay_docs: ${{ inputs.overlay_docs }} - github_access_token: ${{ secrets.github_access_token }} - action: validate - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - working_directory: ${{ inputs.working_directory }} - languages: ${{ inputs.languages }} - - uses: actions/upload-artifact@v3 - if: always() - with: - name: openapi-doc - path: ${{ steps.validate.outputs.openapi_doc }} - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "OpenAPI Document Validation Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - RESOLVED_SPEAKEASY_VERSION: ${{ steps.validate.outputs.resolved_speakeasy_version }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - generate: - name: Generate SDK - runs-on: ubuntu-latest - needs: validate - outputs: - python_regenerated: ${{ steps.generate.outputs.python_regenerated }} - python_directory: ${{ steps.generate.outputs.python_directory }} - typescript_regenerated: ${{ steps.generate.outputs.typescript_regenerated }} - typescript_directory: ${{ steps.generate.outputs.typescript_directory }} - go_regenerated: ${{ steps.generate.outputs.go_regenerated }} - go_directory: ${{ steps.generate.outputs.go_directory }} - terraform_regenerated: ${{ steps.generate.outputs.terraform_regenerated }} - terraform_directory: ${{ steps.generate.outputs.terraform_directory }} - java_regenerated: ${{ steps.generate.outputs.java_regenerated }} - java_directory: ${{ steps.generate.outputs.java_directory }} - php_regenerated: ${{ steps.generate.outputs.php_regenerated }} - php_directory: ${{ steps.generate.outputs.php_directory }} - ruby_regenerated: ${{ steps.generate.outputs.ruby_regenerated }} - ruby_directory: ${{ steps.generate.outputs.ruby_directory }} - csharp_regenerated: ${{ steps.generate.outputs.csharp_regenerated }} - csharp_directory: ${{ steps.generate.outputs.csharp_directory }} - swift_regenerated: ${{ steps.generate.outputs.swift_regenerated }} - swift_directory: ${{ steps.generate.outputs.swift_directory }} - unity_regenerated: ${{ steps.generate.outputs.unity_regenerated }} - unity_directory: ${{ steps.generate.outputs.unity_directory }} - docs_regenerated: ${{ steps.generate.outputs.docs_regenerated }} - docs_directory: ${{ steps.generate.outputs.docs_directory }} - branch_name: ${{ steps.generate.outputs.branch_name }} - previous_gen_version: ${{ steps.generate.outputs.previous_gen_version }} - resolved_speakeasy_version: ${{ steps.generate.outputs.resolved_speakeasy_version }} - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - id: generate - uses: speakeasy-api/sdk-generation-action@v14 - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - openapi_doc_location: ${{ inputs.openapi_doc_location }} - openapi_doc_auth_header: ${{ inputs.openapi_doc_auth_header }} - openapi_doc_auth_token: ${{ secrets.openapi_doc_auth_token }} - openapi_docs: ${{ inputs.openapi_docs }} - overlay_docs: ${{ inputs.overlay_docs }} - github_access_token: ${{ secrets.github_access_token }} - languages: ${{ inputs.languages }} - docs_languages: ${{ inputs.docs_languages }} - create_release: ${{ inputs.create_release }} - publish_python: ${{ inputs.publish_python }} - publish_typescript: ${{ inputs.publish_typescript }} - publish_terraform: ${{ inputs.publish_terraform }} - publish_java: ${{ inputs.publish_java }} - publish_php: ${{ inputs.publish_php }} - publish_ruby: ${{ inputs.publish_ruby }} - publish_csharp: ${{ inputs.publish_csharp }} - mode: ${{ inputs.mode }} - action: generate - force: ${{ inputs.force }} - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - output_tests: ${{ inputs.output_tests }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - working_directory: ${{ inputs.working_directory }} - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "SDK Generation Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - RESOLVED_SPEAKEASY_VERSION: ${{ steps.generate.outputs.resolved_speakeasy_version }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - compile-go: - if: ${{ needs.generate.outputs.go_regenerated == 'true' }} - name: Compile Go SDK - runs-on: ubuntu-latest - needs: generate - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - uses: actions/checkout@v3 - with: - ref: ${{ needs.generate.outputs.branch_name }} - - uses: actions/setup-go@v3 - with: - go-version: ">=1.20.0" - - run: |- - go mod tidy - go build ./... - working-directory: ${{ needs.generate.outputs.go_directory }} - - uses: stefanzweifel/git-auto-commit-action@v5 - with: - commit_message: "chore: update dependencies" - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "Compilation of Go SDK Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - RESOLVED_SPEAKEASY_VERSION: ${{ needs.generate.outputs.resolved_speakeasy_version }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - TARGET_TYPE: "sdk" - compile-terraform: - if: ${{ needs.generate.outputs.terraform_regenerated == 'true' }} - name: Compile Terraform Provider - runs-on: ubuntu-latest - needs: generate - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - uses: actions/checkout@v3 - with: - ref: ${{ needs.generate.outputs.branch_name }} - fetch-depth: 0 - - run: git fetch --force --tags - - uses: actions/setup-go@v3 - with: - go-version: ">=1.20.0" - - run: go build ./... - working-directory: ${{ needs.generate.outputs.terraform_directory }} - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "Compilation of Terraform Provider Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - RESOLVED_SPEAKEASY_VERSION: ${{ needs.generate.outputs.resolved_speakeasy_version }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - TARGET_TYPE: "sdk" - compile-java: - if: ${{ needs.generate.outputs.java_regenerated == 'true' }} - name: Compile Java SDK - runs-on: ubuntu-latest - needs: generate - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - uses: actions/checkout@v3 - with: - ref: ${{ needs.generate.outputs.branch_name }} - - uses: actions/setup-java@v3 - with: - distribution: "corretto" - java-version: "11" - cache: "gradle" - - run: |- - pwd - ./gradlew build --no-daemon -x test && ./gradlew javadoc - working-directory: ${{ needs.generate.outputs.java_directory }} - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "Compilation of Java SDK Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - RESOLVED_SPEAKEASY_VERSION: ${{ needs.generate.outputs.resolved_speakeasy_version }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - TARGET_TYPE: "sdk" - compile-python: - if: ${{ needs.generate.outputs.python_regenerated == 'true' }} - name: Compile Python SDK - runs-on: ubuntu-latest - needs: generate - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - uses: actions/checkout@v3 - with: - ref: ${{ needs.generate.outputs.branch_name }} - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: "3.8" - - run: pip install -e .[dev] - working-directory: ${{ needs.generate.outputs.python_directory }} - - run: python3.8 -m compileall -q . - working-directory: ${{ needs.generate.outputs.python_directory }} - - run: pylint src - working-directory: ${{ needs.generate.outputs.python_directory }} - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "Compilation of Python SDK Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - RESOLVED_SPEAKEASY_VERSION: ${{ needs.generate.outputs.resolved_speakeasy_version }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - TARGET_TYPE: "sdk" - compile-typescript: - if: ${{ needs.generate.outputs.typescript_regenerated == 'true' }} - name: Compile Typescript SDK - runs-on: ubuntu-latest - needs: generate - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - uses: actions/checkout@v3 - with: - ref: ${{ needs.generate.outputs.branch_name }} - - name: Set up Node - uses: actions/setup-node@v3 - with: - node-version: "16.x" - registry-url: "https://registry.npmjs.org" - - run: |- - npm install - tsc --noEmit --skipLibCheck - npx eslint --max-warnings=0 src/** - working-directory: ${{ needs.generate.outputs.typescript_directory }} - - uses: stefanzweifel/git-auto-commit-action@v5 - with: - commit_message: "chore: update dependencies" - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "Compilation of Typescript SDK Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - RESOLVED_SPEAKEASY_VERSION: ${{ needs.generate.outputs.resolved_speakeasy_version }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - TARGET_TYPE: "sdk" - compile-php: - if: ${{ needs.generate.outputs.php_regenerated == 'true' }} - name: Compile PHP SDK - runs-on: ubuntu-latest - needs: generate - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - uses: actions/checkout@v3 - with: - ref: ${{ needs.generate.outputs.branch_name }} - - name: Set up PHP - uses: shivammathur/setup-php@v2 - with: - php-version: "8.1" - tools: composer - - run: composer install && vendor/bin/phpstan analyse src --level 7 --memory-limit 1G --no-progress - working-directory: ${{ needs.generate.outputs.php_directory }} - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "Compilation of PHP SDK Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - RESOLVED_SPEAKEASY_VERSION: ${{ needs.generate.outputs.resolved_speakeasy_version }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - TARGET_TYPE: "sdk" - compile-ruby: - if: ${{ needs.generate.outputs.ruby_regenerated == 'true' }} - name: Compile Ruby SDK - runs-on: ubuntu-latest - needs: generate - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - uses: actions/checkout@v3 - with: - ref: ${{ needs.generate.outputs.branch_name }} - - name: Set up Ruby - uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1 - with: - ruby-version: "3.1" - - run: gem build && bundle install && rake rubocop - working-directory: ${{ needs.generate.outputs.ruby_directory }} - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "Compilation of Ruby SDK Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - RESOLVED_SPEAKEASY_VERSION: ${{ needs.generate.outputs.resolved_speakeasy_version }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - TARGET_TYPE: "sdk" - compile-csharp: - if: ${{ needs.generate.outputs.csharp_regenerated == 'true' }} - name: Compile C# SDK - runs-on: ubuntu-latest - needs: generate - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - uses: actions/checkout@v3 - with: - ref: ${{ needs.generate.outputs.branch_name }} - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - with: - dotnet-version: ${{ inputs.dotnet_version }} - - - name: Compile 5.X - if: ${{ startsWith(inputs.dotnet_version, '5') }} - run: dotnet build - working-directory: ${{ needs.generate.outputs.csharp_directory }} - - - name: Compile 6.X - if: ${{ startsWith(inputs.dotnet_version, '6') }} - run: dotnet format && dotnet build - working-directory: ${{ needs.generate.outputs.csharp_directory }} - - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "Compilation of C# SDK Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - RESOLVED_SPEAKEASY_VERSION: ${{ needs.generate.outputs.resolved_speakeasy_version }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - TARGET_TYPE: "sdk" - compile-swift: - if: ${{ needs.generate.outputs.swift_regenerated == 'true' }} - name: Compile Swift SDK - runs-on: macos-latest - timeout-minutes: 30 - needs: generate - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - uses: actions/checkout@v3 - with: - ref: ${{ needs.generate.outputs.branch_name }} - - - run: xcodebuild -scheme $(xcodebuild -list -json | jq -r ".workspace.schemes[0]") -destination "$(xcrun simctl list --json | jq -r '[.runtimes[] | select(.platform=="iOS") as $runtime | .supportedDeviceTypes | map(select(.productFamily=="iPhone")) | last | "platform=iOS Simulator,OS=" + $runtime.version + ",name=" + .name][0]')" | xcpretty; exit "${PIPESTATUS[0]}" - working-directory: ${{ needs.generate.outputs.swift_directory }} - - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "Compilation of Swift SDK Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - RESOLVED_SPEAKEASY_VERSION: ${{ needs.generate.outputs.resolved_speakeasy_version }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - TARGET_TYPE: "sdk" - compile-unity: - if: ${{ needs.generate.outputs.unity_regenerated == 'true' }} - name: Compile Unity SDK - runs-on: ubuntu-latest - needs: generate - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - uses: actions/checkout@v3 - with: - ref: ${{ needs.generate.outputs.branch_name }} - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - with: - dotnet-version: "5.x" - - - run: echo "Currently not implemented" - working-directory: ${{ needs.generate.outputs.unity_directory }} - - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "Compilation of Unity SDK Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - RESOLVED_SPEAKEASY_VERSION: ${{ needs.generate.outputs.resolved_speakeasy_version }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - TARGET_TYPE: "sdk" - compile-docs: - if: ${{ needs.generate.outputs.docs_regenerated == 'true' }} - name: Compile SDK Docs - runs-on: ubuntu-latest - needs: generate - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - uses: actions/checkout@v3 - with: - ref: ${{ needs.generate.outputs.branch_name }} - - name: Set up Node - uses: actions/setup-node@v3 - with: - node-version: "16.x" - registry-url: "https://registry.npmjs.org" - - name: Install pnpm - run: npm install -g pnpm - - run: pnpm i && pnpm run build - working-directory: ${{ needs.generate.outputs.docs_directory }} - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "Compilation of Docs Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - RESOLVED_SPEAKEASY_VERSION: ${{ needs.generate.outputs.resolved_speakeasy_version }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - TARGET_TYPE: "docs" - finalize: - name: Finalize SDK - if: | - always() && - !contains(needs.*.result, 'failure') && - !contains(needs.*.result, 'cancelled') && - (needs.compile-go.result != 'skipped' || - needs.compile-terraform.result != 'skipped' || - needs.compile-java.result != 'skipped' || - needs.compile-python.result != 'skipped' || - needs.compile-typescript.result != 'skipped' || - needs.compile-php.result != 'skipped' || - needs.compile-ruby.result != 'skipped' || - needs.compile-csharp.result != 'skipped' || - needs.compile-swift.result != 'skipped' || - needs.compile-docs.result != 'skipped' || - needs.compile-unity.result != 'skipped') - needs: - - generate - - compile-go - - compile-terraform - - compile-java - - compile-python - - compile-typescript - - compile-php - - compile-ruby - - compile-csharp - - compile-swift - - compile-unity - - compile-docs - runs-on: ubuntu-latest - outputs: - commit_hash: ${{ steps.finalize.outputs.commit_hash }} - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - id: Finalize - uses: speakeasy-api/sdk-generation-action@v14 - with: - github_access_token: ${{ secrets.github_access_token }} - languages: ${{ inputs.languages }} - create_release: ${{ inputs.create_release }} - publish_python: ${{ inputs.publish_python }} - publish_typescript: ${{ inputs.publish_typescript }} - publish_terraform: ${{ inputs.publish_terraform }} - publish_java: ${{ inputs.publish_java }} - publish_php: ${{ inputs.publish_php }} - publish_ruby: ${{ inputs.publish_ruby }} - publish_csharp: ${{ inputs.publish_csharp }} - mode: ${{ inputs.mode }} - action: finalize - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - branch_name: ${{ needs.generate.outputs.branch_name }} - previous_gen_version: ${{ needs.generate.outputs.previous_gen_version }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "SDK Finalization Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - publish-pypi: - if: ${{ always() && needs.generate.outputs.python_regenerated == 'true' && inputs.publish_python == 'true' && inputs.mode != 'pr' }} - name: Publish Python SDK - runs-on: ubuntu-latest - needs: [generate, compile-python, finalize] - defaults: - run: - working-directory: ${{ needs.generate.outputs.python_directory }} - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - uses: actions/checkout@v3 - with: - ref: ${{ needs.finalize.outputs.commit_hash }} - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: "3.8" - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install setuptools wheel twine - - name: Build and publish - env: - TWINE_USERNAME: __token__ - TWINE_PASSWORD: ${{ secrets.pypi_token }} - run: | - python setup.py sdist bdist_wheel - twine upload dist/* - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "Publishing of Python SDK Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - TARGET_TYPE: "sdk" - publish-npm: - if: ${{ always() && needs.generate.outputs.typescript_regenerated == 'true' && inputs.publish_typescript == 'true' && inputs.mode != 'pr' }} - name: Publish Typescript SDK - runs-on: ubuntu-latest - needs: [generate, compile-typescript, finalize] - defaults: - run: - working-directory: ${{ needs.generate.outputs.typescript_directory }} - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - uses: actions/checkout@v3 - with: - ref: ${{ needs.finalize.outputs.commit_hash }} - - name: Set up Node - uses: actions/setup-node@v3 - with: - node-version: "16.x" - registry-url: "https://registry.npmjs.org" - - name: Install dependencies - run: npm install - - name: Publish - env: - NODE_AUTH_TOKEN: ${{ secrets.npm_token }} - run: npm publish --access public - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "Publishing of Typescript SDK Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - TARGET_TYPE: "sdk" - publish-java: - if: | - always() && - needs.generate.outputs.java_regenerated == 'true' && - inputs.publish_java == 'true' && - inputs.mode != 'pr' - name: Publish Java SDK - runs-on: ubuntu-latest - needs: [generate, compile-java, finalize] - defaults: - run: - working-directory: ${{ needs.generate.outputs.java_directory }} - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - uses: actions/checkout@v3 - with: - ref: ${{ needs.finalize.outputs.commit_hash }} - - name: Set up Java - uses: actions/setup-java@v3 - with: - java-version: "11" - distribution: "corretto" - cache: "gradle" - - name: Publish to Sonatype (legacy) - run: |- - pwd - ./gradlew publish --no-daemon - if: ${{ inputs.use_sonatype_central != 'true' }} - env: - MAVEN_USERNAME: ${{ secrets.ossrh_username }} - MAVEN_PASSWORD: ${{ secrets.ossrh_password }} - ORG_GRADLE_PROJECT_signingKey: ${{ secrets.java_gpg_secret_key }} - ORG_GRADLE_PROJECT_signingPassphrase: ${{ secrets.java_gpg_passphrase }} - - name: Publish to Sonatype Central - run: |- - pwd - ./gradlew build sonatypeCentralUpload --no-daemon - if: ${{ inputs.use_sonatype_central == 'true' }} - env: - SONATYPE_USERNAME: ${{ secrets.ossrh_username }} - SONATYPE_PASSWORD: ${{ secrets.ossrh_password }} - SONATYPE_SIGNING_KEY: ${{ secrets.java_gpg_secret_key }} - SIGNING_KEY_PASSPHRASE: ${{ secrets.java_gpg_passphrase }} - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "Publishing of Java SDK Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - TARGET_TYPE: "sdk" - publish-gems: - if: ${{ always() && needs.generate.outputs.ruby_regenerated == 'true' && inputs.publish_ruby == 'true' && inputs.mode != 'pr' }} - name: Publish Ruby SDK - runs-on: ubuntu-latest - needs: [generate, compile-ruby, finalize] - defaults: - run: - working-directory: ${{ needs.generate.outputs.ruby_directory }} - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - uses: actions/checkout@v3 - with: - ref: ${{ needs.finalize.outputs.commit_hash }} - - name: Set up Ruby - uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1 - with: - ruby-version: "3.1" - - name: Install dependencies - run: gem build && bundle install && rake rubocop - - name: Publish - env: - GEM_HOST_API_KEY: ${{ secrets.rubygems_auth_token }} - run: | - mkdir -p $HOME/.gem - touch $HOME/.gem/credentials - chmod 0600 $HOME/.gem/credentials - printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials - gem build *.gemspec - gem push *.gem - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "Publishing of Ruby SDK Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - TARGET_TYPE: "sdk" - publish-nuget: - if: ${{ always() && needs.generate.outputs.csharp_regenerated == 'true' && inputs.publish_csharp == 'true' && inputs.mode != 'pr' }} - name: Publish C# SDK - runs-on: ubuntu-latest - needs: [generate, compile-csharp, finalize] - defaults: - run: - working-directory: ${{ needs.generate.outputs.csharp_directory }} - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - uses: actions/checkout@v3 - with: - ref: ${{ needs.finalize.outputs.commit_hash }} - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - with: - dotnet-version: ${{ inputs.dotnet_version }} - - name: Publish - run: dotnet pack -o . && dotnet nuget push *.nupkg --api-key ${{ secrets.nuget_api_key }} --source https://api.nuget.org/v3/index.json - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "Publishing of C# SDK Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - TARGET_TYPE: "sdk" - publish-packagist: - if: ${{ always() && needs.generate.outputs.php_regenerated == 'true' && inputs.publish_php == 'true' && inputs.mode != 'pr' }} - name: Publish PHP SDK - runs-on: ubuntu-latest - needs: [generate, compile-php, finalize] - defaults: - run: - working-directory: ${{ needs.generate.outputs.php_directory }} - steps: - - name: Tune GitHub-hosted runner network - uses: smorimoto/tune-github-hosted-runner-network@v1 - - name: Publish - uses: speakeasy-api/packagist-update@support-github-creation - with: - username: ${{ secrets.packagist_username }} - api_token: ${{ secrets.packagist_token }} - package_name: ${{ github.repository }} - package_base_url: ${{ github.server_url }} - - uses: ravsamhq/notify-slack-action@v2 - if: always() && env.SLACK_WEBHOOK_URL != '' - with: - status: ${{ job.status }} - token: ${{ secrets.github_access_token }} - notify_when: "failure" - notification_title: "Publishing of PHP SDK Failed" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - id: log-result - uses: speakeasy-api/sdk-generation-action@v14 - if: always() - with: - speakeasy_version: ${{ inputs.speakeasy_version }} - github_access_token: ${{ secrets.github_access_token }} - action: log-result - speakeasy_api_key: ${{ secrets.speakeasy_api_key }} - speakeasy_server_url: ${{ inputs.speakeasy_server_url }} - languages: ${{ inputs.languages }} - env: - GH_ACTION_RESULT: ${{ job.status }} - GH_ACTION_VERSION: "v14" - GH_ACTION_STEP: ${{ github.job }} - TARGET_TYPE: "sdk" diff --git a/.github/workflows/sdk-publish.yaml b/.github/workflows/sdk-publish.yaml index 45ef5382..8bfe5a11 100644 --- a/.github/workflows/sdk-publish.yaml +++ b/.github/workflows/sdk-publish.yaml @@ -3,51 +3,6 @@ name: Speakeasy SDK Publish Workflow on: workflow_call: inputs: - create_release: - description: "Create a Github release" - default: "true" - required: false - type: string - publish_python: - description: "Publish the Python SDK to PyPi if using 'direct' mode or prepare a release if using 'pr' mode" - default: "false" - required: false - type: string - publish_typescript: - description: "Publish the Typescript SDK to NPM if using 'direct' mode or prepare a release if using 'pr' mode" - default: "false" - required: false - type: string - publish_java: - description: "Publish the Java SDK to the OSSRH URL configured in gen.yml if using 'direct' mode or prepare a release if using 'pr' mode" - default: "false" - required: false - type: string - use_sonatype_central: - description: "When publishing the Java SDK, use the Sonatype central portal" - default: "false" - required: false - type: string - publish_php: - description: "Publish the PHP SDK for Composer if using 'direct' mode or prepare a release if using 'pr' mode" - default: "false" - required: false - type: string - publish_ruby: - description: "Publish the Ruby SDK for RubyGems if using 'direct' mode or prepare a release if using 'pr' mode" - default: "false" - required: false - type: string - publish_csharp: - description: "Publish the C# SDK for nuget if using 'direct' mode or prepare a release if using 'pr' mode" - default: "false" - required: false - type: string - publish_terraform: - description: "Create a Github release compatible with the terraform registry of the provider" - default: "false" - required: false - type: string speakeasy_server_url: required: false description: "Internal use only" @@ -102,6 +57,13 @@ jobs: name: Create Github Release runs-on: ubuntu-latest outputs: + publish_python: ${{ steps.release.outputs.publish_python }} + publish_typescript: ${{ steps.release.outputs.publish_typescript }} + publish_terraform: ${{ steps.release.outputs.publish_terraform }} + publish_java: ${{ steps.release.outputs.publish_java }} + publish_php: ${{ steps.release.outputs.publish_php }} + publish_ruby: ${{ steps.release.outputs.publish_ruby }} + publish_csharp: ${{ steps.release.outputs.publish_csharp }} python_regenerated: ${{ steps.release.outputs.python_regenerated }} python_directory: ${{ steps.release.outputs.python_directory }} typescript_regenerated: ${{ steps.release.outputs.typescript_regenerated }} @@ -124,17 +86,9 @@ jobs: - name: Tune GitHub-hosted runner network uses: smorimoto/tune-github-hosted-runner-network@v1 - id: release - uses: speakeasy-api/sdk-generation-action@v14 + uses: speakeasy-api/sdk-generation-action@v15 with: github_access_token: ${{ secrets.github_access_token }} - create_release: ${{ inputs.create_release }} - publish_python: ${{ inputs.publish_python }} - publish_typescript: ${{ inputs.publish_typescript }} - publish_terraform: ${{ inputs.publish_terraform }} - publish_java: ${{ inputs.publish_java }} - publish_php: ${{ inputs.publish_php }} - publish_ruby: ${{ inputs.publish_ruby }} - publish_csharp: ${{ inputs.publish_csharp }} action: "release" speakeasy_api_key: ${{ secrets.speakeasy_api_key }} speakeasy_server_url: ${{ inputs.speakeasy_server_url }} @@ -150,7 +104,7 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} publish-pypi: - if: ${{ needs.release.outputs.python_regenerated == 'true' && inputs.publish_python == 'true' }} + if: ${{ needs.release.outputs.python_regenerated == 'true' && needs.release.outputs.publish_python == 'true' }} name: Publish Python SDK runs-on: ubuntu-latest needs: release @@ -188,7 +142,7 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} publish-npm: - if: ${{ needs.release.outputs.typescript_regenerated == 'true' && inputs.publish_typescript == 'true' }} + if: ${{ needs.release.outputs.typescript_regenerated == 'true' && needs.release.outputs.publish_typescript == 'true' }} name: Publish Typescript SDK runs-on: ubuntu-latest needs: release @@ -222,7 +176,7 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} publish-java: - if: ${{ needs.release.outputs.java_regenerated == 'true' && inputs.publish_java == 'true' }} + if: ${{ needs.release.outputs.java_regenerated == 'true' && needs.release.outputs.publish_java == 'true' }} name: Publish Java SDK runs-on: ubuntu-latest needs: release @@ -243,7 +197,7 @@ jobs: run: |- pwd ./gradlew publish --no-daemon - if: ${{ inputs.use_sonatype_central != 'true' }} + if: ${{ needs.release.outputs.use_sonatype_legacy == 'true' }} env: MAVEN_USERNAME: ${{ secrets.ossrh_username }} MAVEN_PASSWORD: ${{ secrets.ossrh_password }} @@ -253,7 +207,7 @@ jobs: run: |- pwd ./gradlew build sonatypeCentralUpload --no-daemon - if: ${{ inputs.use_sonatype_central == 'true' }} + if: ${{ needs.release.outputs.use_sonatype_legacy != 'true' }} env: SONATYPE_USERNAME: ${{ secrets.ossrh_username }} SONATYPE_PASSWORD: ${{ secrets.ossrh_password }} @@ -271,7 +225,7 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} publish-packagist: - if: ${{ needs.release.outputs.php_regenerated == 'true' && inputs.publish_php == 'true' }} + if: ${{ needs.release.outputs.php_regenerated == 'true' && needs.release.outputs.publish_php == 'true' }} name: Publish PHP SDK runs-on: ubuntu-latest needs: release @@ -300,7 +254,7 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} publish-nuget: - if: ${{ needs.release.outputs.csharp_regenerated == 'true' && inputs.publish_csharp == 'true' }} + if: ${{ needs.release.outputs.csharp_regenerated == 'true' && needs.release.outputs.publish_csharp == 'true' }} name: Publish C# SDK runs-on: ubuntu-latest needs: release @@ -329,7 +283,7 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} publish-terraform: - if: ${{ needs.release.outputs.terraform_regenerated == 'true' && inputs.publish_terraform == 'true' }} + if: ${{ needs.release.outputs.terraform_regenerated == 'true' && needs.release.outputs.publish_terraform == 'true' }} name: Publish Terraform Provider runs-on: ubuntu-latest needs: release @@ -347,7 +301,7 @@ jobs: gpg_private_key: ${{ secrets.TERRAFORM_GPG_PRIVATE_KEY }} passphrase: ${{ secrets.TERRAFORM_GPG_PASSPHRASE }} - id: release - uses: speakeasy-api/sdk-generation-action@v14 + uses: speakeasy-api/sdk-generation-action@v15 with: github_access_token: ${{ secrets.github_access_token }} speakeasy_api_key: ${{ secrets.speakeasy_api_key }} @@ -368,7 +322,7 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} publish-gems: - if: ${{ needs.release.outputs.ruby_regenerated == 'true' && inputs.publish_ruby == 'true' }} + if: ${{ needs.release.outputs.ruby_regenerated == 'true' && needs.release.outputs.publish_ruby == 'true' }} name: Publish Ruby SDK runs-on: ubuntu-latest needs: release diff --git a/.github/workflows/workflow-executor.yaml b/.github/workflows/workflow-executor.yaml new file mode 100644 index 00000000..1e15c7db --- /dev/null +++ b/.github/workflows/workflow-executor.yaml @@ -0,0 +1,504 @@ +name: Speakeasy SDK Generation Workflow + +on: + workflow_call: + inputs: + speakeasy_version: + description: The version of the Speakeasy CLI to use or "latest" + default: latest + required: false + type: string + mode: + description: |- + The mode to run the workflow in, valid options are 'direct' or 'pr', defaults to 'direct'. + - 'direct' will create a commit with the changes to the SDKs and push them directly to the branch the workflow is configure to run on (normally 'main' or 'master'). + If publishing and creating a release are configured this will happen immediately after the commit is created on the branch. + - 'pr' will instead create a new branch to commit the changes to the SDKs to and then create a PR from this branch. + The sdk-publish workflow will then need to be configured to run when the PR is merged to publish the SDKs and create a release. + See documentation for more details. + default: "direct" + required: false + type: string + force: + description: "Force the generation of the SDKs" + default: "false" + required: false + type: string + speakeasy_server_url: + required: false + description: "Internal use only" + type: string + working_directory: + description: "The working directory for running Speakeasy CLI commands in the action" + required: false + type: string + secrets: + github_access_token: + description: A GitHub access token with write access to the repo + required: true + pypi_token: + description: A PyPi access token for publishing the package to PyPi, include the `pypi-` prefix + required: false + npm_token: + description: An NPM access token for publishing the package to NPM, include the `npm_` prefix + required: false + packagist_username: + description: A Packagist username for publishing the package to Packagist + required: false + packagist_token: + description: A Packagist API token for publishing the package to Packagist + required: false + openapi_doc_auth_token: + description: The auth token to use when fetching the OpenAPI document if it is not publicly hosted. For example `Bearer ` or ``. + required: false + speakeasy_api_key: + description: The API key to use to authenticate the Speakeasy CLI + required: true + ossrh_username: + description: A username for publishing the Java package to the OSSRH URL provided in gen.yml + required: false + ossrh_password: + description: The corresponding password for publishing the Java package to the OSSRH URL provided in gen.yml + required: false + java_gpg_secret_key: + description: The GPG secret key to use for signing the Java package + required: false + java_gpg_passphrase: + description: The passphrase for the GPG secret key + required: false + slack_webhook_url: + description: A Slack webhook URL that pipeline failures will be posted to + required: false + terraform_gpg_secret_key: + description: The GPG secret key to use for signing the Terraform provider + required: false + terraform_gpg_passphrase: + description: The passphrase for the Terraform GPG secret key + required: false + rubygems_auth_token: + description: The auth token (api key) for publishing to RubyGems + required: false + nuget_api_key: + description: The api key for publishing to the Nuget registry + required: false +jobs: + run-workflow: + name: Generate Target + runs-on: ubuntu-latest + outputs: + publish_python: ${{ steps.run-workflow.outputs.publish_python }} + publish_typescript: ${{ steps.run-workflow.outputs.publish_typescript }} + publish_terraform: ${{ steps.run-workflow.outputs.publish_terraform }} + publish_java: ${{ steps.run-workflow.outputs.publish_java }} + publish_php: ${{ steps.run-workflow.outputs.publish_php }} + publish_ruby: ${{ steps.run-workflow.outputs.publish_ruby }} + publish_csharp: ${{ steps.run-workflow.outputs.publish_csharp }} + python_regenerated: ${{ steps.run-workflow.outputs.python_regenerated }} + python_directory: ${{ steps.run-workflow.outputs.python_directory }} + typescript_regenerated: ${{ steps.run-workflow.outputs.typescript_regenerated }} + typescript_directory: ${{ steps.run-workflow.outputs.typescript_directory }} + go_regenerated: ${{ steps.run-workflow.outputs.go_regenerated }} + go_directory: ${{ steps.run-workflow.outputs.go_directory }} + terraform_regenerated: ${{ steps.run-workflow.outputs.terraform_regenerated }} + terraform_directory: ${{ steps.run-workflow.outputs.terraform_directory }} + java_regenerated: ${{ steps.run-workflow.outputs.java_regenerated }} + java_directory: ${{ steps.run-workflow.outputs.java_directory }} + php_regenerated: ${{ steps.run-workflow.outputs.php_regenerated }} + php_directory: ${{ steps.run-workflow.outputs.php_directory }} + ruby_regenerated: ${{ steps.run-workflow.outputs.ruby_regenerated }} + ruby_directory: ${{ steps.run-workflow.outputs.ruby_directory }} + csharp_regenerated: ${{ steps.run-workflow.outputs.csharp_regenerated }} + csharp_directory: ${{ steps.run-workflow.outputs.csharp_directory }} + swift_regenerated: ${{ steps.run-workflow.outputs.swift_regenerated }} + swift_directory: ${{ steps.run-workflow.outputs.swift_directory }} + unity_regenerated: ${{ steps.run-workflow.outputs.unity_regenerated }} + unity_directory: ${{ steps.run-workflow.outputs.unity_directory }} + docs_regenerated: ${{ steps.run-workflow.outputs.docs_regenerated }} + docs_directory: ${{ steps.run-workflow.outputs.docs_directory }} + branch_name: ${{ steps.run-workflow.outputs.branch_name }} + previous_gen_version: ${{ steps.run-workflow.outputs.previous_gen_version }} + resolved_speakeasy_version: ${{ steps.run-workflow.outputs.resolved_speakeasy_version }} + steps: + - name: Tune GitHub-hosted runner network + uses: smorimoto/tune-github-hosted-runner-network@v1 + - id: run-workflow + name: Run Generation Workflow + uses: speakeasy-api/sdk-generation-action@v15 + with: + speakeasy_version: ${{ inputs.speakeasy_version }} + github_access_token: ${{ secrets.github_access_token }} + mode: ${{ inputs.mode }} + force: ${{ inputs.force }} + speakeasy_api_key: ${{ secrets.speakeasy_api_key }} + output_tests: ${{ inputs.output_tests }} + speakeasy_server_url: ${{ inputs.speakeasy_server_url }} + working_directory: ${{ inputs.working_directory }} + - uses: ravsamhq/notify-slack-action@v2 + if: always() && env.SLACK_WEBHOOK_URL != '' + with: + status: ${{ job.status }} + token: ${{ secrets.github_access_token }} + notify_when: "failure" + notification_title: "SDK Generation Failed" + message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" + footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + - id: log-result + name: Log Generation Output + uses: speakeasy-api/sdk-generation-action@v15 + if: always() + with: + speakeasy_version: ${{ inputs.speakeasy_version }} + github_access_token: ${{ secrets.github_access_token }} + action: log-result + speakeasy_api_key: ${{ secrets.speakeasy_api_key }} + speakeasy_server_url: ${{ inputs.speakeasy_server_url }} + env: + GH_ACTION_RESULT: ${{ job.status }} + RESOLVED_SPEAKEASY_VERSION: ${{ steps.run-workflow.outputs.resolved_speakeasy_version }} + GH_ACTION_VERSION: "v14" + GH_ACTION_STEP: ${{ github.job }} + publish-pypi: + if: ${{ always() && + !contains(needs.*.result, 'failure') && + !contains(needs.*.result, 'cancelled') && + needs.run-workflow.outputs.python_regenerated == 'true' && + needs.run-workflow.outputs.publish_python == 'true' + && inputs.mode != 'pr' }} + name: Publish Python SDK + runs-on: ubuntu-latest + needs: [ run-workflow ] + defaults: + run: + working-directory: ${{ needs.run-workflow.outputs.python_directory }} + steps: + - name: Tune GitHub-hosted runner network + uses: smorimoto/tune-github-hosted-runner-network@v1 + - uses: actions/checkout@v3 + with: + ref: ${{ needs.run-workflow.outputs.commit_hash }} + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.8" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install setuptools wheel twine + - name: Build and publish + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.pypi_token }} + run: | + python setup.py sdist bdist_wheel + twine upload dist/* + - uses: ravsamhq/notify-slack-action@v2 + if: always() && env.SLACK_WEBHOOK_URL != '' + with: + status: ${{ job.status }} + token: ${{ secrets.github_access_token }} + notify_when: "failure" + notification_title: "Publishing of Python SDK Failed" + message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" + footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + - id: log-result + uses: speakeasy-api/sdk-generation-action@v15 + if: always() + with: + speakeasy_version: ${{ inputs.speakeasy_version }} + github_access_token: ${{ secrets.github_access_token }} + action: log-result + speakeasy_api_key: ${{ secrets.speakeasy_api_key }} + speakeasy_server_url: ${{ inputs.speakeasy_server_url }} + env: + GH_ACTION_RESULT: ${{ job.status }} + GH_ACTION_VERSION: "v14" + GH_ACTION_STEP: ${{ github.job }} + TARGET_TYPE: "sdk" + publish-npm: + if: ${{ always() && + !contains(needs.*.result, 'failure') && + !contains(needs.*.result, 'cancelled') && + needs.run-workflow.outputs.typescript_regenerated == 'true' && + needs.run-workflow.outputs.publish_typescript == 'true' + && inputs.mode != 'pr' }} + name: Publish Typescript SDK + runs-on: ubuntu-latest + needs: [ run-workflow ] + defaults: + run: + working-directory: ${{ needs.run-workflow.outputs.typescript_directory }} + steps: + - name: Tune GitHub-hosted runner network + uses: smorimoto/tune-github-hosted-runner-network@v1 + - uses: actions/checkout@v3 + with: + ref: ${{ needs.run-workflow.outputs.commit_hash }} + - name: Set up Node + uses: actions/setup-node@v3 + with: + node-version: "16.x" + registry-url: "https://registry.npmjs.org" + - name: Install dependencies + run: npm install + - name: Publish + env: + NODE_AUTH_TOKEN: ${{ secrets.npm_token }} + run: npm publish --access public + - uses: ravsamhq/notify-slack-action@v2 + if: always() && env.SLACK_WEBHOOK_URL != '' + with: + status: ${{ job.status }} + token: ${{ secrets.github_access_token }} + notify_when: "failure" + notification_title: "Publishing of Typescript SDK Failed" + message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" + footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + - id: log-result + uses: speakeasy-api/sdk-generation-action@v15 + if: always() + with: + speakeasy_version: ${{ inputs.speakeasy_version }} + github_access_token: ${{ secrets.github_access_token }} + action: log-result + speakeasy_api_key: ${{ secrets.speakeasy_api_key }} + speakeasy_server_url: ${{ inputs.speakeasy_server_url }} + env: + GH_ACTION_RESULT: ${{ job.status }} + GH_ACTION_VERSION: "v14" + GH_ACTION_STEP: ${{ github.job }} + TARGET_TYPE: "sdk" + publish-java: + if: ${{ always() && + !contains(needs.*.result, 'failure') && + !contains(needs.*.result, 'cancelled') && + needs.run-workflow.outputs.java_regenerated == 'true' && + needs.run-workflow.outputs.publish_java == 'true' + && inputs.mode != 'pr' }} + name: Publish Java SDK + runs-on: ubuntu-latest + needs: [ run-workflow ] + defaults: + run: + working-directory: ${{ needs.run-workflow.outputs.java_directory }} + steps: + - name: Tune GitHub-hosted runner network + uses: smorimoto/tune-github-hosted-runner-network@v1 + - uses: actions/checkout@v3 + with: + ref: ${{ needs.run-workflow.outputs.commit_hash }} + - name: Set up Java + uses: actions/setup-java@v3 + with: + java-version: "11" + distribution: "corretto" + - name: Validate Gradle wrapper + uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b + - name: Publish to Sonatype (legacy) + if: ${{ inputs.use_sonatype_central != 'true' }} + uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1 + with: + arguments: publish + env: + MAVEN_USERNAME: ${{ secrets.ossrh_username }} + MAVEN_PASSWORD: ${{ secrets.ossrh_password }} + ORG_GRADLE_PROJECT_signingKey: ${{ secrets.java_gpg_secret_key }} + ORG_GRADLE_PROJECT_signingPassphrase: ${{ secrets.java_gpg_passphrase }} + - name: Publish to Sonatype Central + if: ${{ inputs.use_sonatype_central == 'true' }} + run: |- + pwd + ./gradlew build sonatypeCentralUpload --no-daemon + env: + SONATYPE_USERNAME: ${{ secrets.ossrh_username }} + SONATYPE_PASSWORD: ${{ secrets.ossrh_password }} + SONATYPE_SIGNING_KEY: ${{ secrets.java_gpg_secret_key }} + SIGNING_KEY_PASSPHRASE: ${{ secrets.java_gpg_passphrase }} + - uses: ravsamhq/notify-slack-action@v2 + if: always() && env.SLACK_WEBHOOK_URL != '' + with: + status: ${{ job.status }} + token: ${{ secrets.github_access_token }} + notify_when: "failure" + notification_title: "Publishing of Java SDK Failed" + message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" + footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + - id: log-result + uses: speakeasy-api/sdk-generation-action@v15 + if: always() + with: + speakeasy_version: ${{ inputs.speakeasy_version }} + github_access_token: ${{ secrets.github_access_token }} + action: log-result + speakeasy_api_key: ${{ secrets.speakeasy_api_key }} + speakeasy_server_url: ${{ inputs.speakeasy_server_url }} + env: + GH_ACTION_RESULT: ${{ job.status }} + GH_ACTION_VERSION: "v14" + GH_ACTION_STEP: ${{ github.job }} + TARGET_TYPE: "sdk" + publish-gems: + if: ${{ always() && + !contains(needs.*.result, 'failure') && + !contains(needs.*.result, 'cancelled') && + needs.run-workflow.outputs.ruby_regenerated == 'true' && + needs.run-workflow.outputs.publish_ruby == 'true' + && inputs.mode != 'pr' }} + name: Publish Ruby SDK + runs-on: ubuntu-latest + needs: [ run-workflow ] + defaults: + run: + working-directory: ${{ needs.run-workflow.outputs.ruby_directory }} + steps: + - name: Tune GitHub-hosted runner network + uses: smorimoto/tune-github-hosted-runner-network@v1 + - uses: actions/checkout@v3 + with: + ref: ${{ needs.run-workflow.outputs.commit_hash }} + - name: Set up Ruby + uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1 + with: + ruby-version: "3.1" + - name: Install dependencies + run: gem build && bundle install && rake rubocop + - name: Publish + env: + GEM_HOST_API_KEY: ${{ secrets.rubygems_auth_token }} + run: | + mkdir -p $HOME/.gem + touch $HOME/.gem/credentials + chmod 0600 $HOME/.gem/credentials + printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials + gem build *.gemspec + gem push *.gem + - uses: ravsamhq/notify-slack-action@v2 + if: always() && env.SLACK_WEBHOOK_URL != '' + with: + status: ${{ job.status }} + token: ${{ secrets.github_access_token }} + notify_when: "failure" + notification_title: "Publishing of Ruby SDK Failed" + message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" + footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + - id: log-result + uses: speakeasy-api/sdk-generation-action@v15 + if: always() + with: + speakeasy_version: ${{ inputs.speakeasy_version }} + github_access_token: ${{ secrets.github_access_token }} + action: log-result + speakeasy_api_key: ${{ secrets.speakeasy_api_key }} + speakeasy_server_url: ${{ inputs.speakeasy_server_url }} + env: + GH_ACTION_RESULT: ${{ job.status }} + GH_ACTION_VERSION: "v14" + GH_ACTION_STEP: ${{ github.job }} + TARGET_TYPE: "sdk" + publish-nuget: + if: ${{ always() && + !contains(needs.*.result, 'failure') && + !contains(needs.*.result, 'cancelled') && + needs.run-workflow.outputs.csharp_regenerated == 'true' && + needs.run-workflow.outputs.publish_csharp == 'true' + && inputs.mode != 'pr' }} + name: Publish C# SDK + runs-on: ubuntu-latest + needs: [ run-workflow ] + defaults: + run: + working-directory: ${{ needs.run-workflow.outputs.csharp_directory }} + steps: + - name: Tune GitHub-hosted runner network + uses: smorimoto/tune-github-hosted-runner-network@v1 + - uses: actions/checkout@v3 + with: + ref: ${{ needs.run-workflow.outputs.commit_hash }} + - name: Setup dotnet + uses: actions/setup-dotnet@v3 + with: + dotnet-version: ${{ inputs.dotnet_version }} + - name: Publish + run: dotnet pack -o . && dotnet nuget push *.nupkg --api-key ${{ secrets.nuget_api_key }} --source https://api.nuget.org/v3/index.json + - uses: ravsamhq/notify-slack-action@v2 + if: always() && env.SLACK_WEBHOOK_URL != '' + with: + status: ${{ job.status }} + token: ${{ secrets.github_access_token }} + notify_when: "failure" + notification_title: "Publishing of C# SDK Failed" + message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" + footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + - id: log-result + uses: speakeasy-api/sdk-generation-action@v15 + if: always() + with: + speakeasy_version: ${{ inputs.speakeasy_version }} + github_access_token: ${{ secrets.github_access_token }} + action: log-result + speakeasy_api_key: ${{ secrets.speakeasy_api_key }} + speakeasy_server_url: ${{ inputs.speakeasy_server_url }} + env: + GH_ACTION_RESULT: ${{ job.status }} + GH_ACTION_VERSION: "v14" + GH_ACTION_STEP: ${{ github.job }} + TARGET_TYPE: "sdk" + publish-packagist: + if: ${{ always() && + !contains(needs.*.result, 'failure') && + !contains(needs.*.result, 'cancelled') && + needs.run-workflow.outputs.php_regenerated == 'true' && + needs.run-workflow.outputs.publish_php == 'true' + && inputs.mode != 'pr' }} + name: Publish PHP SDK + runs-on: ubuntu-latest + needs: [ run-workflow ] + defaults: + run: + working-directory: ${{ needs.run-workflow.outputs.php_directory }} + steps: + - name: Tune GitHub-hosted runner network + uses: smorimoto/tune-github-hosted-runner-network@v1 + - name: Publish + uses: speakeasy-api/packagist-update@support-github-creation + with: + username: ${{ secrets.packagist_username }} + api_token: ${{ secrets.packagist_token }} + package_name: ${{ github.repository }} + package_base_url: ${{ github.server_url }} + - uses: ravsamhq/notify-slack-action@v2 + if: always() && env.SLACK_WEBHOOK_URL != '' + with: + status: ${{ job.status }} + token: ${{ secrets.github_access_token }} + notify_when: "failure" + notification_title: "Publishing of PHP SDK Failed" + message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" + footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Run>" + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + - id: log-result + uses: speakeasy-api/sdk-generation-action@v15 + if: always() + with: + speakeasy_version: ${{ inputs.speakeasy_version }} + github_access_token: ${{ secrets.github_access_token }} + action: log-result + speakeasy_api_key: ${{ secrets.speakeasy_api_key }} + speakeasy_server_url: ${{ inputs.speakeasy_server_url }} + env: + GH_ACTION_RESULT: ${{ job.status }} + GH_ACTION_VERSION: "v14" + GH_ACTION_STEP: ${{ github.job }} + TARGET_TYPE: "sdk" diff --git a/Dockerfile b/Dockerfile index b88232e5..ab1abeef 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ ## Build -FROM golang:1.21-alpine as builder +FROM golang:1.21-alpine3.18 as builder WORKDIR /app @@ -15,11 +15,50 @@ COPY pkg/ ./pkg/ RUN go build -o /action ## Deploy -FROM golang:1.21-alpine +FROM golang:1.21-alpine3.18 RUN apk update RUN apk add git +### Install Node +RUN apk add --update --no-cache nodejs npm + +### Install Python +RUN apk add --update --no-cache python3 py3-pip python3-dev + +### Install Java +RUN apk add --update --no-cache openjdk11 gradle + +### Install Ruby +RUN apk add --update --no-cache build-base ruby ruby-bundler ruby-dev + +### Install .NET 6.0 +ENV DOTNET_ROOT=/usr/lib/dotnet +RUN apk add --update --no-cache dotnet6-sdk + +# Install .NET 5.0 +RUN apk add --update --no-cache curl bash openssl1.1-compat +RUN curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin -Channel 5.0 -InstallDir ${DOTNET_ROOT} +RUN dotnet --list-sdks + +### Install PHP and Composer +#### Source: https://github.com/geshan/docker-php-composer-alpine/blob/master/Dockerfile +RUN apk --update --no-cache add wget \ + curl \ + git \ + php \ + php-ctype php-dom php-json php-mbstring php-phar php-tokenizer php-xml php-xmlwriter \ + php-curl \ + php-openssl \ + php-iconv \ + --repository http://nl.alpinelinux.org/alpine/edge/testing/ +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer +RUN mkdir -p /var/www +WORKDIR /var/www +COPY . /var/www +VOLUME /var/www +### END PHP + WORKDIR / COPY --from=builder /action /action diff --git a/README.md b/README.md index 8c4522b5..6a537560 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,6 @@ jobs: uses: speakeasy-api/sdk-generation-action/.github/workflows/sdk-publish.yaml@v14 # Import the sdk publish workflow which will handle the publishing to the package managers with: publish_python: true # Tells the publish action to publish the Python SDK to PyPi - create_release: true secrets: github_access_token: ${{ secrets.GITHUB_TOKEN }} pypi_token: ${{ secrets.PYPI_TOKEN }} @@ -253,8 +252,6 @@ Distribution of Swift SDKs is supported using the [Swift Package Manager](https: As such publishing a Swift package through the action creates a new git tag (and corresponding GitHub release) which allows the SDK to be easily imported into Swift projects by the GitHub repository's URL and corresponding version. -**Note:** Because of the requirement on git tags and GitHub releases, the value of `create_release` is ignored when publishing a Swift SDK through the action. - ### Terraform Registry Publishing a generated terraform provider is possible through the configuration of this action. In order to publish, you must do the following: @@ -309,7 +306,7 @@ The action to run, valid options are `validate`, `generate`, `finalize`, `sugges The mode to run the action in, valid options are `direct` or `pr`, defaults to `direct`. -- `direct` will create a commit with the changes to the SDKs and push them directly to the branch the workflow is configure to run on (normally 'main' or 'master'). If `create_release` is `true` this will happen immediately after the commit is created on the branch. +- `direct` will create a commit with the changes to the SDKs and push them directly to the branch the workflow is configure to run on (normally 'main' or 'master'). - `pr` will instead create a new branch to commit the changes to the SDKs to and then create a PR from this branch. The sdk-publish workflow will then need to be configured to run when the PR is merged to publish the SDKs and create a release. ### `speakeasy_version` @@ -391,11 +388,6 @@ languages: | If multiple languages are present we will treat the repo as a mono repo, if a single language is present as a single language repo. -### `create_release` - -Whether to create a release for the new SDK version if using `direct` mode. Default `"true"`. -This will also create a tag for the release, allowing the Go SDK to be retrieved via a tag with Go modules. - ### `publish_python` **(Workflow Only)** Whether to publish the Python SDK to PyPi. Default `"false"`. diff --git a/action.yml b/action.yml index 053a5592..a3bb1302 100644 --- a/action.yml +++ b/action.yml @@ -1,123 +1,14 @@ # action.yml -name: Speakeasy Client SDK Generation Action +name: Speakeasy SDK Workflow Runner Action (alpha) description: The Speakeasy Generation Action isto be run via the workflows provided in this repo and is not intended to be run directly. inputs: speakeasy_version: description: The version of the Speakeasy CLI to use or "latest" default: latest required: false - openapi_doc_location: - description: The location of the OpenAPI document to use, either a relative path within the repo or a URL to a publicly hosted document - required: false - deprecationMessage: "This input is deprecated, please use the `openapi_docs` input instead." - openapi_doc_auth_header: - description: |- - The auth header to use when fetching the OpenAPI document if it is not publicly hosted. For example `Authorization`. - If using a private speakeasy hosted document use `x-api-key`. This header will be populated with the openapi_doc_auth_token provided. - required: false - openapi_doc_auth_token: - description: The auth token to use when fetching the OpenAPI document if it is not publicly hosted. For example `Bearer ` or ``. - required: false - openapi_docs: - description: |- - A yaml string containing a list of OpenAPI documents to use, if multiple documents are provided they will be merged together, prior to generation. - - If the document lives within the repo a relative path can be provided, if the document is hosted publicly a URL can be provided. - - If the documents are hosted privately a URL can be provided along with the `openapi_doc_auth_header` and `openapi_doc_auth_token` inputs. - Each document will be fetched using the provided auth header and token, so they need to be valid for all documents. - - For example: - openapi_docs: | - - https://example.com/openapi1.json - - https://example.com/openapi2.json - required: false - overlay_docs: - description: |- - A yaml string containing a list of overlay documents to use, if multiple documents are provided they will be applied to the OpenAPI document in the order provided. - - If the document lives within the repo a relative path can be provided, if the document is hosted publicly a URL can be provided. - - If the documents are hosted privately a URL can be provided along with the `openapi_doc_auth_header` and `openapi_doc_auth_token` inputs. - Each document will be fetched using the provided auth header and token, so they need to be valid for all documents. - - For example: - overlay_docs: | - - https://example.com/overlay1.json - - https://example.com/overlay2.json - openapi_doc_output: - description: "The path to output the modified OpenAPI spec" - required: false - default: "./openapi.yaml" github_access_token: description: A GitHub access token with write access to the repo required: true - languages: - description: |- - A yaml string containing a list of languages to generate SDKs for example: - languages: | - - go: ./go-sdk # specifying a output directory - - python # using default output of ./python-client-sdk - - typescript # using default output of ./typescript-client-sdk - - java # using default output of ./java-client-sdk - - php # using default output of ./php-client-sdk - - ruby # using default output of ./ruby-client-sdk - - terraform # (single language repo only) - - csharp # using default output of ./csharp-client-sdk - - unity # using default output of ./unity-client-sdk - - swift # using default output of ./swift-client-sdk - - docs # generation target for sdk docs - If multiple languages are present we will treat this repo as a mono repo, if a single language is present as a single language repo and generate the sdk - in the root of the repo if not path is provided. - required: false - docs_languages: - description: |- - A yaml string containing a list of languages to generate SDK docs for example: - languages: | - - go - - python - - typescript - - java - - csharp - - unity - - curl - required: false - create_release: - description: "Create a Github release on generation" - default: "true" - required: false - publish_python: - description: "Whether the Python SDK will be published to PyPi" - default: "false" - required: false - publish_typescript: - description: "Whether the Typescript SDK will be published to NPM" - default: "false" - required: false - publish_terraform: - description: "Whether the Terraform Provider will be published to the Terraform Registry" - default: "false" - required: false - publish_php: - description: "Whether the PHP SDK will be published to Packagist this will also create a release on Github" - default: "false" - required: false - publish_ruby: - description: "Whether the Ruby SDK will be published to Rubygems" - default: "false" - required: false - publish_java: - description: "Whether the Java SDK will be published to the provided OSSRH URL" - default: "false" - required: false - use_sonatype_central: - description: "When publishing the Java SDK, use the Sonatype central portal" - default: "false" - required: false - publish_csharp: - description: "Whether the C# SDK will be published to Nuget" - default: "false" - required: false speakeasy_api_key: description: "The Speakeasy API key to authenticate the Speakeasy CLI with" required: true @@ -140,10 +31,10 @@ inputs: required: false action: description: |- - The current action step to run, valid options are 'validate', 'generate', 'suggest', 'finalize', 'finalize-suggestion', or 'release', defaults to 'generate'. + The current action step to run, valid options are 'validate', 'run-workflow', 'suggest', 'finalize', 'finalize-suggestion', or 'release', defaults to 'run-workflow'. This is intended to be used along with the `mode` input to determine the current action step to run. - 'validate' will validate the OpenAPI document and return addressable warnings and errors. - - 'generate' will generate the SDK and commit the changes to the branch. + - 'run-workflow' will generate the SDK and commit the changes to the branch. - 'suggest' will apply suggestions to the OpenAPI document and commit the changes to the branch. - 'finalize' depending on mode will either merge the branch to the branch the workflow is configure to run on (normally 'main' or 'master') or create a pull request. - 'finalize-suggestion' will create a pull request with the suggestions from the LLM model. @@ -173,6 +64,20 @@ inputs: description: "The GPG fingerprint to sign the release with" required: false outputs: + publish_python: + description: "Whether the Python SDK will be published to PyPi" + publish_typescript: + description: "Whether the Typescript SDK will be published to NPM" + publish_terraform: + description: "Whether the Terraform Provider will be published to the Terraform Registry" + publish_php: + description: "Whether the PHP SDK will be published to Packagist this will also create a release on Github" + publish_ruby: + description: "Whether the Ruby SDK will be published to Rubygems" + publish_java: + description: "Whether the Java SDK will be published to the provided OSSRH URL" + publish_csharp: + description: "Whether the C# SDK will be published to Nuget" python_regenerated: description: "true if the Python SDK was regenerated" python_directory: @@ -229,34 +134,21 @@ outputs: description: "The location of the OpenAPI document used for generation" runs: using: "docker" - image: "docker://ghcr.io/speakeasy-api/sdk-generation-action:v14" + image: "docker://ghcr.io/speakeasy-api/sdk-generation-action:v15" env: SPEAKEASY_API_KEY: ${{ inputs.speakeasy_api_key }} SPEAKEASY_SERVER_URL: ${{ inputs.speakeasy_server_url }} OPENAI_API_KEY: ${{ inputs.openai_api_key }} args: - ${{ inputs.speakeasy_version }} - - ${{ inputs.openapi_doc_location }} - ${{ inputs.github_access_token }} - - ${{ inputs.languages }} - ${{ inputs.docs_languages }} - - ${{ inputs.create_release }} - - ${{ inputs.publish_python }} - - ${{ inputs.publish_typescript }} - - ${{ inputs.publish_php }} - - ${{ inputs.publish_ruby }} - - ${{ inputs.publish_java }} - - ${{ inputs.publish_terraform }} - - ${{ inputs.publish_csharp }} - - ${{ inputs.openapi_doc_auth_header }} - - ${{ inputs.openapi_doc_auth_token }} - ${{ inputs.max_suggestions }} - ${{ inputs.mode }} - ${{ inputs.action }} - ${{ inputs.branch_name }} - ${{ inputs.cli_output }} - ${{ inputs.previous_gen_version }} - - ${{ inputs.openapi_docs }} - ${{ inputs.openapi_doc_output }} - ${{ inputs.output_tests }} - ${{ inputs.working_directory }} diff --git a/go.mod b/go.mod index 200ff4cd..b2a27f3a 100644 --- a/go.mod +++ b/go.mod @@ -1,18 +1,18 @@ module github.com/speakeasy-api/sdk-generation-action -go 1.21 +go 1.21.0 require ( github.com/go-git/go-git/v5 v5.11.0 github.com/google/go-github/v54 v54.0.0 github.com/google/uuid v1.6.0 github.com/hashicorp/go-version v1.6.0 - github.com/pb33f/libopenapi v0.13.8 + github.com/pb33f/libopenapi v0.14.0 github.com/speakeasy-api/git-diff-parser v0.0.3 - github.com/speakeasy-api/sdk-gen-config v1.5.1 + github.com/speakeasy-api/sdk-gen-config v1.7.4 github.com/speakeasy-api/speakeasy-client-sdk-go/v3 v3.4.1 github.com/stretchr/testify v1.8.4 - golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb + golang.org/x/exp v0.0.0-20231127185646-65229373498e golang.org/x/oauth2 v0.11.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -22,35 +22,38 @@ require ( github.com/AlekSi/pointer v1.2.0 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect + github.com/bahlo/generic-list-go v0.2.0 // indirect + github.com/buger/jsonparser v1.1.1 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cloudflare/circl v1.3.3 // indirect github.com/cyphar/filepath-securejoin v0.2.4 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/ericlagergren/decimal v0.0.0-20240305081647-93d586550569 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect - github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect - github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/sergi/go-diff v1.2.0 // indirect github.com/skeema/knownhosts v1.2.1 // indirect github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect + github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect golang.org/x/crypto v0.16.0 // indirect - golang.org/x/mod v0.12.0 // indirect + golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.19.0 // indirect - golang.org/x/sync v0.3.0 // indirect + golang.org/x/sync v0.5.0 // indirect golang.org/x/sys v0.15.0 // indirect - golang.org/x/tools v0.13.0 // indirect + golang.org/x/tools v0.16.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff --git a/go.sum b/go.sum index 744d0c94..0c2a4c63 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,3 @@ -cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w= @@ -13,6 +11,10 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= +github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= @@ -24,8 +26,9 @@ github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUK github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= @@ -36,8 +39,9 @@ github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FM github.com/ericlagergren/decimal v0.0.0-20240305081647-93d586550569 h1:PNe5U6Gc0FAVbptp1BXy1ZYi8MyBoeIBWLU2DBH9YnA= github.com/ericlagergren/decimal v0.0.0-20240305081647-93d586550569/go.mod h1:M9R1FoZ3y//hwwnJtO51ypFGwm8ZfpxPT/ZLtO1mcgQ= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= @@ -83,8 +87,7 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -94,10 +97,10 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lucasjones/reggen v0.0.0-20200904144131-37ba4fa293bb/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mmcloughlin/avo v0.5.0/go.mod h1:ChHFdoV7ql95Wi7vuq2YT1bwCJqiWdZrQ1im3VujLYM= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -114,33 +117,30 @@ github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAl github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= -github.com/pb33f/libopenapi v0.13.8 h1:PzBTpN1jdTi/XJpHGiRomxSHfQHdabcasGXW8yEhIjw= -github.com/pb33f/libopenapi v0.13.8/go.mod h1:Lv2eEtsAtbRFlF8hjH82L8SIGoUNgemMVoKoB6A9THk= +github.com/pb33f/libopenapi v0.14.0 h1:sXcq6z5vG/QPbSLxYSjCMQAhszZD4+Yox60HBzcB2gI= +github.com/pb33f/libopenapi v0.14.0/go.mod h1:m+4Pwri31UvcnZjuP8M7TlbR906DXJmMvYsbis234xg= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= -github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= -github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/speakeasy-api/git-diff-parser v0.0.3 h1:LL12d+HMtSyj6O/hQqIn/lgDPYI6ci/DEhk0la/xA+0= github.com/speakeasy-api/git-diff-parser v0.0.3/go.mod h1:P46HmmVVmwA9P8h2wa0fDpmRM8/grbVQ+uKhWDtpkIY= -github.com/speakeasy-api/sdk-gen-config v1.5.1 h1:TmX2mvUgWmnljs0nrVnkYpu6pzXZYdUCBSy3bgE3f5I= -github.com/speakeasy-api/sdk-gen-config v1.5.1/go.mod h1:uwL/q5GJqxqSWer0s3xTXR8bwY+ByRzN++D6WfAJMbw= +github.com/speakeasy-api/sdk-gen-config v1.7.4 h1:hk3GaKiL6zxx3SulnxdunvU2V7bUSQ4YviXtIiUmWuo= +github.com/speakeasy-api/sdk-gen-config v1.7.4/go.mod h1:4R+8FTyM6UdLHltOVAigIoR5D2UfPsGMmEFzPOP1yCs= github.com/speakeasy-api/speakeasy-client-sdk-go/v3 v3.4.1 h1:7bnCFOsWDhce7m0Btgsxjq30ZGlluXDm21hI6qj2BPc= github.com/speakeasy-api/speakeasy-client-sdk-go/v3 v3.4.1/go.mod h1:b4fiZ1Wid0JHwwiYqhaPifDwjmC15uiN7A8Cmid+9kw= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -148,6 +148,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= +github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= +github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -161,13 +163,13 @@ golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2Uz golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= -golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb h1:mIKbk8weKhSeLH2GmUTrvx8CjkyJmnU1wFmg59CUjFA= -golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= +golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= @@ -191,8 +193,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -212,7 +214,6 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -241,8 +242,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= +golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/actions/finalize.go b/internal/actions/finalize.go deleted file mode 100644 index d992de0d..00000000 --- a/internal/actions/finalize.go +++ /dev/null @@ -1,105 +0,0 @@ -package actions - -import ( - "errors" - "fmt" - - "github.com/speakeasy-api/sdk-generation-action/internal/cli" - "github.com/speakeasy-api/sdk-generation-action/internal/environment" - "github.com/speakeasy-api/sdk-generation-action/internal/logging" - "github.com/speakeasy-api/sdk-generation-action/pkg/releases" -) - -func Finalize() error { - g, err := initAction() - if err != nil { - return err - } - - branchName := environment.GetBranchName() - if branchName == "" { - return errors.New("branch name is required") - } - - success := false - - defer func() { - if (!success || environment.GetMode() == environment.ModeDirect) && !environment.IsDebugMode() { - if err := g.DeleteBranch(branchName); err != nil { - logging.Debug("failed to delete branch %s: %v", branchName, err) - } - } - }() - - branchName, err = g.FindBranch(branchName) - if err != nil { - return err - } - - switch environment.GetMode() { - case environment.ModePR: - if _, err := cli.Download(environment.GetPinnedSpeakeasyVersion(), g); err != nil { - return err - } - - if !cli.IsAtLeastVersion(cli.MinimumSupportedCLIVersion) { - return fmt.Errorf("action requires at least version %s of the speakeasy CLI", cli.MinimumSupportedCLIVersion) - } - - branchName, pr, err := g.FindExistingPR(branchName, environment.ActionFinalize) - if err != nil { - return err - } - - releaseInfo, err := getReleasesInfo() - if err != nil { - return err - } - - if err := g.CreateOrUpdatePR(branchName, *releaseInfo, environment.GetPreviousGenVersion(), pr); err != nil { - return err - } - case environment.ModeDirect: - releaseInfo, err := getReleasesInfo() - if err != nil { - return err - } - - commitHash, err := g.MergeBranch(branchName) - if err != nil { - return err - } - - if environment.CreateGitRelease() { - if err := g.CreateRelease(*releaseInfo); err != nil { - return err - } - } - - outputs := map[string]string{ - "commit_hash": commitHash, - } - - if err := setOutputs(outputs); err != nil { - return err - } - } - - success = true - - return nil -} - -func getReleasesInfo() (*releases.ReleasesInfo, error) { - releasesDir, err := getReleasesDir() - if err != nil { - return nil, err - } - - releasesInfo, err := releases.GetLastReleaseInfo(releasesDir) - if err != nil { - return nil, err - } - - return releasesInfo, nil -} diff --git a/internal/actions/release.go b/internal/actions/release.go index 8027ac44..c0364757 100644 --- a/internal/actions/release.go +++ b/internal/actions/release.go @@ -3,7 +3,9 @@ package actions import ( "errors" "fmt" + "github.com/speakeasy-api/sdk-generation-action/internal/configuration" "path/filepath" + "strconv" "strings" "github.com/speakeasy-api/sdk-generation-action/internal/environment" @@ -61,9 +63,37 @@ func Release() error { outputs[fmt.Sprintf("%s_directory", lang)] = info.Path } - if err := setOutputs(outputs); err != nil { + if err = addPublishOutputs(dir, outputs); err != nil { return err } + if err = setOutputs(outputs); err != nil { + return err + } + + return nil +} + +func addPublishOutputs(dir string, outputs map[string]string) error { + wf, err := configuration.GetWorkflowAndValidateLanguages(false) + if err != nil { + return err + } + + for _, target := range wf.Targets { + // Only add outputs for the target that was regenerated, based on output directory + if dir != "." && target.Output != nil && *target.Output != dir { + continue + } + + lang := target.Target + published := target.IsPublished() + outputs[fmt.Sprintf("publish_%s", lang)] = fmt.Sprintf("%t", published) + + if published && lang == "java" && target.Publishing.Java != nil { + outputs["use_sonatype_legacy"] = strconv.FormatBool(target.Publishing.Java.UseSonatypeLegacy) + } + } + return nil } diff --git a/internal/actions/generate.go b/internal/actions/runWorkflow.go similarity index 52% rename from internal/actions/generate.go rename to internal/actions/runWorkflow.go index 1ddaf043..fa9dcca1 100644 --- a/internal/actions/generate.go +++ b/internal/actions/runWorkflow.go @@ -3,14 +3,17 @@ package actions import ( "fmt" + "github.com/hashicorp/go-version" + "github.com/speakeasy-api/sdk-generation-action/internal/git" + "github.com/speakeasy-api/sdk-generation-action/internal/run" + "github.com/speakeasy-api/sdk-generation-action/internal/cli" "github.com/speakeasy-api/sdk-generation-action/internal/environment" - "github.com/speakeasy-api/sdk-generation-action/internal/generate" "github.com/speakeasy-api/sdk-generation-action/internal/logging" "github.com/speakeasy-api/sdk-generation-action/pkg/releases" ) -func Generate() error { +func RunWorkflow() error { g, err := initAction() if err != nil { return err @@ -21,8 +24,9 @@ func Generate() error { return err } - if !cli.IsAtLeastVersion(cli.MinimumSupportedCLIVersion) { - return fmt.Errorf("action requires at least version %s of the speakeasy CLI", cli.MinimumSupportedCLIVersion) + minimumVersionForRun := version.Must(version.NewVersion("1.161.0")) + if !cli.IsAtLeastVersion(minimumVersionForRun) { + return fmt.Errorf("action requires at least version %s of the speakeasy CLI", minimumVersionForRun) } mode := environment.GetMode() @@ -31,27 +35,27 @@ func Generate() error { if mode == environment.ModePR { var err error - branchName, _, err = g.FindExistingPR("", environment.ActionGenerate) + branchName, _, err = g.FindExistingPR("", environment.ActionRunWorkflow) if err != nil { return err } } - branchName, err = g.FindOrCreateBranch(branchName, environment.ActionGenerate) + branchName, err = g.FindOrCreateBranch(branchName, environment.ActionRunWorkflow) if err != nil { return err } success := false defer func() { - if !success && !environment.IsDebugMode() { + if (!success || environment.GetMode() == environment.ModeDirect) && !environment.IsDebugMode() { if err := g.DeleteBranch(branchName); err != nil { logging.Debug("failed to delete branch %s: %v", branchName, err) } } }() - genInfo, outputs, err := generate.Generate(g) + genInfo, outputs, err := run.Run(g) if err != nil { if err := setOutputs(outputs); err != nil { logging.Debug("failed to set outputs: %v", err) @@ -60,6 +64,8 @@ func Generate() error { } outputs["resolved_speakeasy_version"] = resolvedVersion + anythingRegenerated := false + if genInfo != nil { docVersion := genInfo.OpenAPIDocVersion speakeasyVersion := genInfo.SpeakeasyVersion @@ -83,6 +89,8 @@ func Generate() error { langGenInfo, ok := genInfo.Languages[lang] if ok && outputs[fmt.Sprintf("%s_regenerated", lang)] == "true" { + anythingRegenerated = true + path := outputs[fmt.Sprintf("%s_directory", lang)] releaseInfo.LanguagesGenerated[lang] = releases.GenerationInfo{ @@ -90,7 +98,7 @@ func Generate() error { Path: path, } - if environment.IsLanguagePublished(lang) { + if published, ok := outputs[fmt.Sprintf("publish_%s", lang)]; ok && published == "true" { releaseInfo.Languages[lang] = releases.LanguageReleaseInfo{ PackageName: langGenInfo.PackageName, Version: langGenInfo.Version, @@ -109,14 +117,12 @@ func Generate() error { return err } - if _, err := g.CommitAndPush(docVersion, speakeasyVersion, "", environment.ActionGenerate); err != nil { + if _, err := g.CommitAndPush(docVersion, speakeasyVersion, "", environment.ActionRunWorkflow); err != nil { return err } } - outputs["branch_name"] = branchName - - if err := setOutputs(outputs); err != nil { + if err = finalize(outputs, branchName, anythingRegenerated, g); err != nil { return err } @@ -124,3 +130,75 @@ func Generate() error { return nil } + +// Sets outputs and creates or adds releases info +func finalize(outputs map[string]string, branchName string, anythingRegenerated bool, g *git.Git) error { + // If nothing was regenerated, we don't need to do anything + if !anythingRegenerated { + return nil + } + + branchName, err := g.FindBranch(branchName) + if err != nil { + return err + } + + defer func() { + outputs["branch_name"] = branchName + + if err := setOutputs(outputs); err != nil { + logging.Debug("failed to set outputs: %v", err) + } + }() + + switch environment.GetMode() { + case environment.ModePR: + branchName, pr, err := g.FindExistingPR(branchName, environment.ActionFinalize) + if err != nil { + return err + } + + releaseInfo, err := getReleasesInfo() + if err != nil { + return err + } + + if err := g.CreateOrUpdatePR(branchName, *releaseInfo, environment.GetPreviousGenVersion(), pr); err != nil { + return err + } + case environment.ModeDirect: + releaseInfo, err := getReleasesInfo() + if err != nil { + return err + } + + commitHash, err := g.MergeBranch(branchName) + if err != nil { + return err + } + + if environment.CreateGitRelease() { + if err := g.CreateRelease(*releaseInfo); err != nil { + return err + } + } + + outputs["commit_hash"] = commitHash + } + + return nil +} + +func getReleasesInfo() (*releases.ReleasesInfo, error) { + releasesDir, err := getReleasesDir() + if err != nil { + return nil, err + } + + releasesInfo, err := releases.GetLastReleaseInfo(releasesDir) + if err != nil { + return nil, err + } + + return releasesInfo, nil +} diff --git a/internal/actions/utils.go b/internal/actions/utils.go index e55db0be..6540dc23 100644 --- a/internal/actions/utils.go +++ b/internal/actions/utils.go @@ -7,15 +7,15 @@ import ( func getReleasesDir() (string, error) { releasesDir := "." // Find releases file - langs, err := configuration.GetAndValidateLanguages(false) + wf, err := configuration.GetWorkflowAndValidateLanguages(false) if err != nil { return "", err } - for _, dir := range langs { + for _, target := range wf.Targets { // If we are only generating one language and its not in the root directory we assume this is a multi-sdk repo - if len(langs) == 1 && dir != "." { - releasesDir = dir + if len(wf.Targets) == 1 && target.Output != nil && *target.Output != "." { + releasesDir = *target.Output } } diff --git a/internal/actions/validate.go b/internal/actions/validate.go deleted file mode 100644 index b2773907..00000000 --- a/internal/actions/validate.go +++ /dev/null @@ -1,59 +0,0 @@ -package actions - -import ( - "fmt" - "strings" - - "github.com/speakeasy-api/sdk-generation-action/internal/cli" - "github.com/speakeasy-api/sdk-generation-action/internal/document" - "github.com/speakeasy-api/sdk-generation-action/internal/environment" - "github.com/speakeasy-api/sdk-generation-action/internal/logging" -) - -func Validate() error { - g, err := initAction() - if err != nil { - return err - } - - resolvedVersion, err := cli.Download(environment.GetPinnedSpeakeasyVersion(), g) - if err != nil { - return err - } - - if !cli.IsAtLeastVersion(cli.MinimumSupportedCLIVersion) { - return fmt.Errorf("action requires at least version %s of the speakeasy CLI", cli.MinimumSupportedCLIVersion) - } - - docPath, _, err := document.GetOpenAPIFileInfo() - if err != nil { - return err - } - docPathPrefix := environment.GetWorkspace() - if !strings.HasSuffix(docPathPrefix, "/") { - docPathPrefix += "/" - } - if err := setOutputs(map[string]string{ - "resolved_speakeasy_version": resolvedVersion, - "openapi_doc": strings.TrimPrefix(docPath, docPathPrefix), - }); err != nil { - logging.Debug("failed to set outputs: %v", err) - } - - // Errors from GetMaxValidation{Warnings,Errors} are very non-fatal, but should be logged. - - var maxWarns, maxErrors int - if maxWarns, err = environment.GetMaxValidationWarnings(); err != nil { - logging.Info("%v", err) - } - - if maxErrors, err = environment.GetMaxValidationErrors(); err != nil { - logging.Info("%v", err) - } - - if err := cli.Validate(docPath, maxWarns, maxErrors); err != nil { - return err - } - - return nil -} diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 62690417..11b28c84 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -1,12 +1,12 @@ package cli import ( + "encoding/json" "fmt" "os" "os/exec" "path/filepath" "regexp" - "strconv" "strings" "github.com/speakeasy-api/sdk-generation-action/internal/environment" @@ -40,6 +40,46 @@ func GetSupportedLanguages() ([]string, error) { return strings.Split(langs, ", "), nil } +func Run(installationURLs map[string]string, repoURL string, repoSubdirectories map[string]string) error { + args := []string{ + "run", + } + + args = append(args, "-t", "all") + + urls, err := json.Marshal(installationURLs) + if err != nil { + return fmt.Errorf("error marshalling installation urls: %w", err) + } + args = append(args, "--installationURLs", string(urls)) + + if repoURL != "" { + args = append(args, "-r", repoURL) + } + + subdirs, err := json.Marshal(repoSubdirectories) + if err != nil { + return fmt.Errorf("error marshalling repo subdirectories: %w", err) + } + args = append(args, "--repo-subdirs", string(subdirs)) + + if environment.ForceGeneration() { + fmt.Println("force input enabled - setting SPEAKEASY_FORCE_GENERATION=true") + os.Setenv("SPEAKEASY_FORCE_GENERATION", "true") + } + + if environment.ShouldOutputTests() { + // TODO: Add CLI flag for outputting tests + } + + out, err := runSpeakeasyCommand(args...) + if err != nil { + return fmt.Errorf("error running workflow: %w - %s", err, out) + } + fmt.Println(out) + return nil +} + func TriggerGoGenerate() error { tidyCmd := exec.Command("go", "mod", "tidy") tidyCmd.Dir = filepath.Join(environment.GetWorkspace(), "repo", environment.GetWorkingDirectory()) @@ -97,30 +137,6 @@ func GetGenerationVersion() (*version.Version, error) { return genVersion, nil } -func GetLatestFeatureVersions(lang string) (map[string]string, error) { - out, err := runSpeakeasyCommand("generate", "sdk", "version", "-l", lang) - if err != nil { - return nil, err - } - - logging.Debug(out) - - r := regexp.MustCompile(`(?m)^ ([a-zA-Z]+): ([0-9]+\.[0-9]+\.[0-9]+)`) - - matches := r.FindAllStringSubmatch(out, -1) - - versions := map[string]string{} - - for _, subMatch := range matches { - feature := subMatch[1] - version := subMatch[2] - - versions[feature] = version - } - - return versions, nil -} - func GetChangelog(lang, genVersion, previousGenVersion string, targetVersions map[string]string, previousVersions map[string]string) (string, error) { targetVersionsStrings := []string{} @@ -157,19 +173,6 @@ func GetChangelog(lang, genVersion, previousGenVersion string, targetVersions ma return out, nil } -func Validate(docPath string, maxValidationWarnings, maxValidationErrors int) error { - var ( - maxWarns = strconv.Itoa(maxValidationWarnings) - maxErrors = strconv.Itoa(maxValidationErrors) - ) - out, err := runSpeakeasyCommand("validate", "openapi", "-s", docPath, "--max-validation-warnings", maxWarns, "--max-validation-errors", maxErrors) - if err != nil { - return fmt.Errorf("error validating openapi: %w - %s", err, out) - } - fmt.Println(out) - return nil -} - func Suggest(docPath, maxSuggestions, docOutputPath string) (string, error) { out, err := runSpeakeasyCommand("suggest", "--schema", docPath, "--auto-approve", "--output-file", docOutputPath, "--max-suggestions", maxSuggestions, "--level", "hint", "--serial") if err != nil { @@ -179,81 +182,6 @@ func Suggest(docPath, maxSuggestions, docOutputPath string) (string, error) { return out, nil } -func Generate(docPath, lang, outputDir, installationURL string, published, outputTests bool, repoURL, repoSubDirectory string) error { - outputDir, err := filepath.Abs(outputDir) - if err != nil { - return err - } - args := []string{ - "generate", - "sdk", - "-s", - docPath, - "-l", - lang, - "-o", - outputDir, - "-y", - } - - args = append(args, "-i", installationURL) - if published { - args = append(args, "-p") - } - - if repoURL != "" { - args = append(args, "-r", repoURL) - } - if repoSubDirectory != "" { - args = append(args, "-b", repoSubDirectory) - } - - if outputTests { - args = append(args, "-t") - } - - if environment.ForceGeneration() { - fmt.Println("force input enabled - setting SPEAKEASY_FORCE_GENERATION=true") - os.Setenv("SPEAKEASY_FORCE_GENERATION", "true") - } - - out, err := runSpeakeasyCommand(args...) - if err != nil { - return fmt.Errorf("error generating sdk: %w - %s", err, out) - } - fmt.Println(out) - return nil -} - -func GenerateDocs(docPath, langs, outputDir string) error { - args := []string{ - "generate", - "docs", - "-s", - docPath, - "-l", - langs, - "-o", - outputDir, - } - - out, err := runSpeakeasyCommand(args...) - if err != nil { - return fmt.Errorf("error generating sdk docs: %w - %s", err, out) - } - fmt.Println(out) - return nil -} - -func ValidateConfig(configDir string) error { - out, err := runSpeakeasyCommand("validate", "config", "-d", configDir) - if err != nil { - return fmt.Errorf("error validating config: %w - %s", err, out) - } - fmt.Println(out) - return nil -} - func MergeDocuments(files []string, output string) error { args := []string{ "merge", diff --git a/internal/configuration/configuration.go b/internal/configuration/configuration.go index 19c6d70b..fa6a080d 100644 --- a/internal/configuration/configuration.go +++ b/internal/configuration/configuration.go @@ -2,77 +2,61 @@ package configuration import ( "fmt" - "path/filepath" - "strings" - + "github.com/speakeasy-api/sdk-gen-config/workflow" "github.com/speakeasy-api/sdk-generation-action/internal/cli" "github.com/speakeasy-api/sdk-generation-action/internal/environment" "golang.org/x/exp/slices" - "gopkg.in/yaml.v3" + "path/filepath" ) -func GetAndValidateLanguages(checkLangSupported bool) (map[string]string, error) { - languages := environment.GetLanguages() - - languages = strings.ReplaceAll(languages, "\\n", "\n") - - langs := []interface{}{} - - if err := yaml.Unmarshal([]byte(languages), &langs); err != nil { - return nil, fmt.Errorf("failed to parse languages: %w", err) +func GetWorkflowAndValidateLanguages(checkLangSupported bool) (*workflow.Workflow, error) { + wf, err := getWorkflow() + if err != nil { + return nil, fmt.Errorf("failed to load workflow file: %w", err) } - if len(langs) == 0 { - return nil, fmt.Errorf("no languages provided") + var langs []string + for _, target := range wf.Targets { + langs = append(langs, target.Target) } - langCfgs := map[string]string{} - - numConfigs := len(langs) - - for _, l := range langs { - langCfg, ok := l.(map[string]interface{}) - if ok { - for l := range langCfg { - path := langCfg[l].(string) + if checkLangSupported { + if err := AssertLangsSupported(langs); err != nil { + return nil, err + } + } - langCfgs[l] = filepath.Clean(path) - } + return wf, nil +} - continue - } +func getWorkflow() (*workflow.Workflow, error) { + workspace := environment.GetWorkspace() - lang, ok := l.(string) - if ok { - if numConfigs > 1 { - langCfgs[lang] = fmt.Sprintf("%s-client-sdk", lang) - } else { - langCfgs[lang] = "" - } - continue - } + localPath := filepath.Join(workspace, "repo") - return nil, fmt.Errorf("invalid language configuration: %v", l) + wf, _, err := workflow.Load(localPath) + if err != nil { + return nil, err } - if !checkLangSupported { - return langCfgs, nil - } + return wf, err +} +func AssertLangsSupported(langs []string) error { supportedLangs, err := cli.GetSupportedLanguages() if err != nil { - return nil, fmt.Errorf("failed to get supported languages: %w", err) + return fmt.Errorf("failed to get supported languages: %w", err) } - for l := range langCfgs { + for _, l := range langs { if l == "docs" { - return langCfgs, nil + return nil } if !slices.Contains(supportedLangs, l) { - return nil, fmt.Errorf("unsupported language: %s", l) + return fmt.Errorf("unsupported language: %s", l) } } - return langCfgs, nil + return nil } diff --git a/internal/environment/environment.go b/internal/environment/environment.go index 8b8acd53..a1681459 100644 --- a/internal/environment/environment.go +++ b/internal/environment/environment.go @@ -19,7 +19,7 @@ type Action string const ( ActionValidate Action = "validate" - ActionGenerate Action = "generate" + ActionRunWorkflow Action = "run-workflow" ActionSuggest Action = "suggest" ActionFinalize Action = "finalize" ActionFinalizeSuggestion Action = "finalize-suggestion" @@ -68,7 +68,7 @@ func GetMode() Mode { func GetAction() Action { action := os.Getenv("INPUT_ACTION") if action == "" { - return ActionGenerate + return ActionRunWorkflow } return Action(action) @@ -140,7 +140,7 @@ func IsDocsGeneration() bool { } func CreateGitRelease() bool { - return os.Getenv("INPUT_CREATE_RELEASE") == "true" || IsLanguagePublished("php") || IsLanguagePublished("terraform") || IsLanguagePublished("swift") + return IsLanguagePublished("php") || IsLanguagePublished("terraform") || IsLanguagePublished("swift") } func GetAccessToken() string { @@ -157,16 +157,12 @@ func GetInvokeTime() time.Time { func IsLanguagePublished(lang string) bool { if lang == "go" || lang == "swift" { - return os.Getenv("INPUT_CREATE_RELEASE") == "true" + return true } return os.Getenv(fmt.Sprintf("INPUT_PUBLISH_%s", strings.ToUpper(lang))) == "true" } -func IsJavaPublished() bool { - return os.Getenv("INPUT_PUBLISH_JAVA") == "true" -} - func GetOpenAPIDocAuthHeader() string { return os.Getenv("INPUT_OPENAPI_DOC_AUTH_HEADER") } diff --git a/internal/git/git.go b/internal/git/git.go index 3a021da1..5d127e47 100644 --- a/internal/git/git.go +++ b/internal/git/git.go @@ -170,7 +170,7 @@ func (g *Git) FindExistingPR(branchName string, action environment.Action) (stri } var prTitle string - if action == environment.ActionGenerate || action == environment.ActionFinalize { + if action == environment.ActionRunWorkflow || action == environment.ActionFinalize { prTitle = getGenPRTitle() } else if action == environment.ActionFinalize || action == environment.ActionFinalizeSuggestion { prTitle = getSuggestPRTitle() @@ -247,7 +247,7 @@ func (g *Git) FindOrCreateBranch(branchName string, action environment.Action) ( return g.FindBranch(branchName) } - if action == environment.ActionGenerate { + if action == environment.ActionRunWorkflow { branchName = fmt.Sprintf("speakeasy-sdk-regen-%d", time.Now().Unix()) } else if action == environment.ActionSuggest { branchName = fmt.Sprintf("speakeasy-openapi-suggestion-%d", time.Now().Unix()) @@ -309,12 +309,12 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act logging.Info("Commit and pushing changes to git") - if _, err := w.Add("."); err != nil { + if err := g.Add("."); err != nil { return "", fmt.Errorf("error adding changes: %w", err) } var commitMessage string - if action == environment.ActionGenerate { + if action == environment.ActionRunWorkflow { commitMessage = fmt.Sprintf("ci: regenerated with OpenAPI Doc %s, Speakeasy CLI %s", openAPIDocVersion, speakeasyVersion) } else if action == environment.ActionSuggest { commitMessage = fmt.Sprintf("ci: suggestions for OpenAPI doc %s", doc) @@ -340,6 +340,18 @@ func (g *Git) CommitAndPush(openAPIDocVersion, speakeasyVersion, doc string, act return commitHash.String(), nil } +func (g *Git) Add(arg string) error { + cmd := exec.Command("git", "add", arg) + cmd.Dir = filepath.Join(environment.GetWorkspace(), "repo", environment.GetWorkingDirectory()) + cmd.Env = os.Environ() + output, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("error running `git add %s`: %w %s", arg, err, string(output)) + } + + return nil +} + func (g *Git) CreateOrUpdatePR(branchName string, releaseInfo releases.ReleasesInfo, previousGenVersion string, pr *github.PullRequest) error { var changelog string var err error @@ -449,7 +461,11 @@ You have exceeded the limit of one free generated SDK. Please reach out to the S MaintainerCanModify: github.Bool(true), }) if err != nil { - return fmt.Errorf("failed to create PR: %w", err) + messageSuffix := "" + if strings.Contains(err.Error(), "GitHub Actions is not permitted to create or approve pull requests") { + messageSuffix += "\nNavigate to Settings > Actions > Workflow permissions and ensure that allow GitHub Actions to create and approve pull requests is checked. For more information see https://www.speakeasyapi.dev/docs/advanced-setup/github-setup." + } + return fmt.Errorf("failed to create PR: %w%s", err, messageSuffix) } } diff --git a/internal/generate/generate.go b/internal/run/run.go similarity index 73% rename from internal/generate/generate.go rename to internal/run/run.go index cec8cc30..3deb2152 100644 --- a/internal/generate/generate.go +++ b/internal/run/run.go @@ -1,17 +1,16 @@ -package generate +package run import ( "fmt" + "github.com/speakeasy-api/sdk-gen-config/workflow" + "github.com/speakeasy-api/sdk-generation-action/internal/configuration" "path" "path/filepath" "strings" config "github.com/speakeasy-api/sdk-gen-config" "github.com/speakeasy-api/sdk-generation-action/internal/cli" - "github.com/speakeasy-api/sdk-generation-action/internal/configuration" - "github.com/speakeasy-api/sdk-generation-action/internal/document" "github.com/speakeasy-api/sdk-generation-action/internal/environment" - "gopkg.in/yaml.v3" ) type LanguageGenInfo struct { @@ -30,20 +29,10 @@ type Git interface { CheckDirDirty(dir string, ignoreMap map[string]string) (bool, string, error) } -func Generate(g Git) (*GenerationInfo, map[string]string, error) { - langs, err := configuration.GetAndValidateLanguages(true) - if err != nil { - return nil, nil, err - } - +func Run(g Git) (*GenerationInfo, map[string]string, error) { workspace := environment.GetWorkspace() outputs := map[string]string{} - docPath, docVersion, err := document.GetOpenAPIFileInfo() - if err != nil { - return nil, nil, err - } - speakeasyVersion, err := cli.GetSpeakeasyVersion() if err != nil { return nil, outputs, fmt.Errorf("failed to get speakeasy version: %w", err) @@ -57,60 +46,85 @@ func Generate(g Git) (*GenerationInfo, map[string]string, error) { globalPreviousGenVersion := "" + wf, err := configuration.GetWorkflowAndValidateLanguages(true) + if err != nil { + return nil, outputs, err + } + langConfigs := map[string]*config.LanguageConfig{} - for lang, dir := range langs { - outputDir := path.Join(workspace, "repo", dir) + installationURLs := map[string]string{} + repoURL := getRepoURL() + repoSubdirectories := map[string]string{} + previousManagementInfos := map[string]config.Management{} + + getDirAndOutputDir := func(target workflow.Target) (string, string) { + dir := "." + if target.Output != nil { + dir = *target.Output + } + + return dir, path.Join(workspace, "repo", dir) + } + + includesTerraform := false + + // Load initial configs + for targetID, target := range wf.Targets { + lang := target.Target + dir, outputDir := getDirAndOutputDir(target) // Load the config so we can get the current version information loadedCfg, err := config.Load(outputDir) if err != nil { return nil, outputs, err } - previousManagementInfo := loadedCfg.LockFile.Management + previousManagementInfos[targetID] = loadedCfg.LockFile.Management globalPreviousGenVersion, err = getPreviousGenVersion(loadedCfg.LockFile, lang, globalPreviousGenVersion) if err != nil { return nil, outputs, err } - fmt.Printf("Generating %s SDK in %s\n", lang, outputDir) + published := target.IsPublished() + outputs[fmt.Sprintf("publish_%s", lang)] = fmt.Sprintf("%t", published) + fmt.Printf("Generating %s SDK in %s", lang, outputDir) - published := environment.IsLanguagePublished(lang) installationURL := getInstallationURL(lang, dir) if installationURL == "" { published = true // Treat as published if we don't have an installation URL } - repoURL, repoSubdirectory := getRepoDetails(dir) + if installationURL != "" { + installationURLs[targetID] = installationURL + } + if dir != "." { + repoSubdirectories[targetID] = filepath.Clean(dir) + } + if lang == "terraform" { + includesTerraform = true + } + } - if lang == "docs" { - docsLanguages := environment.GetDocsLanguages() - docsLanguages = strings.ReplaceAll(docsLanguages, "\\n", "\n") - docsLangs := []string{} - if err := yaml.Unmarshal([]byte(docsLanguages), &docsLangs); err != nil { - return nil, outputs, fmt.Errorf("failed to parse docs languages: %w", err) - } + // Run the workflow + if err := cli.Run(installationURLs, repoURL, repoSubdirectories); err != nil { + return nil, outputs, err + } - if err := cli.GenerateDocs(docPath, strings.Join(docsLangs, ","), outputDir); err != nil { - return nil, outputs, err - } - } else if lang == "terraform" { - if err := cli.Generate(docPath, lang, outputDir, installationURL, published, environment.ShouldOutputTests(), repoURL, repoSubdirectory); err != nil { - return nil, outputs, err - } - // Also trigger "go generate ./..." to regenerate docs - if err = cli.TriggerGoGenerate(); err != nil { - return nil, outputs, err - } - } else { - if err := cli.Generate(docPath, lang, outputDir, installationURL, published, environment.ShouldOutputTests(), repoURL, repoSubdirectory); err != nil { - return nil, outputs, err - } + // For terraform, we also trigger "go generate ./..." to regenerate docs + if includesTerraform { + if err = cli.TriggerGoGenerate(); err != nil { + return nil, outputs, err } + } + + // Check for changes + for targetID, target := range wf.Targets { + lang := target.Target + dir, outputDir := getDirAndOutputDir(target) // Load the config again so we can compare the versions - loadedCfg, err = config.Load(outputDir) + loadedCfg, err := config.Load(outputDir) if err != nil { return nil, outputs, err } @@ -118,13 +132,9 @@ func Generate(g Git) (*GenerationInfo, map[string]string, error) { langCfg := loadedCfg.Config.Languages[lang] langConfigs[lang] = &langCfg - dirForOutput := dir - if dirForOutput == "" { - dirForOutput = "." - } - - outputs[fmt.Sprintf("%s_directory", lang)] = dirForOutput + outputs[fmt.Sprintf("%s_directory", lang)] = dir + previousManagementInfo := previousManagementInfos[targetID] dirty, dirtyMsg, err := g.CheckDirDirty(dir, map[string]string{ previousManagementInfo.ReleaseVersion: currentManagementInfo.ReleaseVersion, previousManagementInfo.GenerationVersion: currentManagementInfo.GenerationVersion, @@ -182,8 +192,8 @@ func Generate(g Git) (*GenerationInfo, map[string]string, error) { genInfo = &GenerationInfo{ SpeakeasyVersion: speakeasyVersion.String(), GenerationVersion: generationVersion.String(), - OpenAPIDocVersion: docVersion, - Languages: langGenInfo, + //OpenAPIDocVersion: docVersion, //TODO + Languages: langGenInfo, } } @@ -258,8 +268,6 @@ func getInstallationURL(lang, subdirectory string) string { return "" } -func getRepoDetails(subdirectory string) (string, string) { - subdirectory = filepath.Clean(subdirectory) - - return fmt.Sprintf("%s/%s.git", environment.GetGithubServerURL(), environment.GetRepo()), subdirectory +func getRepoURL() string { + return fmt.Sprintf("%s/%s.git", environment.GetGithubServerURL(), environment.GetRepo()) } diff --git a/main.go b/main.go index c4ac6007..fcb7d1a6 100644 --- a/main.go +++ b/main.go @@ -38,25 +38,22 @@ func main() { err = telemetry.Track(context.Background(), shared.InteractionTypeCiExec, func(ctx context.Context, event *shared.CliEvent) error { switch environment.GetAction() { - case environment.ActionValidate: - return actions.Validate() - case environment.ActionSuggest: - return actions.Suggest() - case environment.ActionGenerate: - return actions.Generate() - case environment.ActionFinalize: - return actions.Finalize() - case environment.ActionFinalizeSuggestion: - return actions.FinalizeSuggestion() - case environment.ActionRelease: - return actions.Release() - case environment.ActionLog: - return actions.LogActionResult() - default: - return fmt.Errorf("unknown action: %s", environment.GetAction()) + case environment.ActionSuggest: + return actions.Suggest() + case environment.ActionRunWorkflow: + return actions.RunWorkflow() + case environment.ActionFinalizeSuggestion: + return actions.FinalizeSuggestion() + case environment.ActionRelease: + return actions.Release() + case environment.ActionLog: + return actions.LogActionResult() + default: + return fmt.Errorf("unknown action: %s", environment.GetAction()) } }) + if err != nil { fmt.Printf("::error title=failed::%v\n", err) os.Exit(1) diff --git a/testing/direct-mode-multi-sdk.env b/testing/direct-mode-multi-sdk.env index 35c8290b..ff66e622 100644 --- a/testing/direct-mode-multi-sdk.env +++ b/testing/direct-mode-multi-sdk.env @@ -1,7 +1,6 @@ INPUT_MODE="direct" INPUT_ACTION="generate" INPUT_LANGUAGES="- go: ./subsdk1" -INPUT_CREATE_RELEASE=true GITHUB_REPOSITORY="speakeasy-api/sdk-generation-action-multi-test-repo" INPUT_FORCE=true RUN_FINALIZE=true \ No newline at end of file diff --git a/testing/direct-mode.env b/testing/direct-mode.env index ffd70dea..708de6b6 100644 --- a/testing/direct-mode.env +++ b/testing/direct-mode.env @@ -1,7 +1,6 @@ INPUT_MODE="direct" INPUT_ACTION="generate" INPUT_LANGUAGES="- go" -INPUT_CREATE_RELEASE=true GITHUB_REPOSITORY="speakeasy-api/sdk-generation-action-test-repo" INPUT_FORCE=true RUN_FINALIZE=true \ No newline at end of file diff --git a/testing/release-mode-multi-sdk.env b/testing/release-mode-multi-sdk.env index 67f45b5b..68f4347a 100644 --- a/testing/release-mode-multi-sdk.env +++ b/testing/release-mode-multi-sdk.env @@ -1,4 +1,3 @@ INPUT_ACTION="release" INPUT_LANGUAGES="- go: ./subsdk1" -INPUT_CREATE_RELEASE=true GITHUB_REPOSITORY="speakeasy-api/sdk-generation-action-multi-test-repo" diff --git a/testing/release-mode.env b/testing/release-mode.env index 94c7a42a..b8c7822f 100644 --- a/testing/release-mode.env +++ b/testing/release-mode.env @@ -1,4 +1,3 @@ INPUT_ACTION="release" INPUT_LANGUAGES="- go" -INPUT_CREATE_RELEASE=true GITHUB_REPOSITORY="speakeasy-api/sdk-generation-action-test-repo" \ No newline at end of file diff --git a/testing/test.sh b/testing/test.sh index c870e3fc..06fddd40 100755 --- a/testing/test.sh +++ b/testing/test.sh @@ -10,12 +10,6 @@ function run_action() { # Default environment variables not subject to change by different tests export INPUT_DEBUG=true -#export INPUT_OPENAPI_DOC_LOCATION="https://docs.speakeasyapi.dev/openapi.yaml" # Uncomment to test deprecated input and comment out INPUT_OPENAPI_DOCS -export INPUT_OPENAPI_DOCS=$(cat <