From 7918fd72e5f7561412812134f34eb90aac6194f1 Mon Sep 17 00:00:00 2001 From: Ulysse Mavrocordatos Date: Fri, 5 Sep 2025 14:02:14 +0200 Subject: [PATCH] Make Ruby test workflow reusable --- .github/workflows/reusable-ci.yml | 70 ++++++++++ .github/workflows/reusable-examples.yml | 45 +++++++ ...tion.yml => reusable-integration-test.yml} | 73 ++++++++--- .github/workflows/reusable-pre-commit.yml | 82 ++++++++++++ .github/workflows/reusable-ruby-test.yml | 66 ++++++++++ .github/workflows/test.yml | 120 +++++------------- 6 files changed, 352 insertions(+), 104 deletions(-) create mode 100644 .github/workflows/reusable-ci.yml create mode 100644 .github/workflows/reusable-examples.yml rename .github/workflows/{test_integration.yml => reusable-integration-test.yml} (58%) create mode 100644 .github/workflows/reusable-pre-commit.yml create mode 100644 .github/workflows/reusable-ruby-test.yml diff --git a/.github/workflows/reusable-ci.yml b/.github/workflows/reusable-ci.yml new file mode 100644 index 000000000000..9f4a3feff75d --- /dev/null +++ b/.github/workflows/reusable-ci.yml @@ -0,0 +1,70 @@ +name: Reusable Complete CI Workflow + +on: + workflow_call: + inputs: + target-branch: + description: 'Branch to checkout and test (defaults to the calling branch)' + required: false + type: string + default: '' + cache-version: + description: 'Cache version for gem dependencies' + required: false + type: string + default: '' + + secrets: + PIPELINE_GITHUB_APP_ID: + required: false + PIPELINE_GITHUB_APP_PRIVATE_KEY: + required: false + # Integration test secrets + DD_API_KEY: + required: false + DD_CLIENT_API_KEY: + required: false + DD_CLIENT_APP_KEY: + required: false + SLEEP_AFTER_REQUEST: + required: false + +jobs: + pre-commit: + uses: ./.github/workflows/reusable-pre-commit.yml + with: + target-branch: ${{ inputs.target-branch }} + enable-commit-changes: false # Don't auto-commit in external CI + secrets: + PIPELINE_GITHUB_APP_ID: ${{ secrets.PIPELINE_GITHUB_APP_ID }} + PIPELINE_GITHUB_APP_PRIVATE_KEY: ${{ secrets.PIPELINE_GITHUB_APP_PRIVATE_KEY }} + + test: + uses: ./.github/workflows/reusable-ruby-test.yml + with: + target-branch: ${{ inputs.target-branch }} + cache-version: ${{ inputs.cache-version }} + secrets: + PIPELINE_GITHUB_APP_ID: ${{ secrets.PIPELINE_GITHUB_APP_ID }} + PIPELINE_GITHUB_APP_PRIVATE_KEY: ${{ secrets.PIPELINE_GITHUB_APP_PRIVATE_KEY }} + DD_API_KEY: ${{ secrets.DD_API_KEY }} + + examples: + uses: ./.github/workflows/reusable-examples.yml + with: + target-branch: ${{ inputs.target-branch }} + cache-version: ${{ inputs.cache-version }} + + integration: + uses: ./.github/workflows/reusable-integration-test.yml + with: + target-branch: ${{ inputs.target-branch }} + cache-version: ${{ inputs.cache-version }} + secrets: + PIPELINE_GITHUB_APP_ID: ${{ secrets.PIPELINE_GITHUB_APP_ID }} + PIPELINE_GITHUB_APP_PRIVATE_KEY: ${{ secrets.PIPELINE_GITHUB_APP_PRIVATE_KEY }} + DD_API_KEY: ${{ secrets.DD_API_KEY }} + DD_CLIENT_API_KEY: ${{ secrets.DD_CLIENT_API_KEY }} + DD_CLIENT_APP_KEY: ${{ secrets.DD_CLIENT_APP_KEY }} + SLEEP_AFTER_REQUEST: ${{ secrets.SLEEP_AFTER_REQUEST }} + diff --git a/.github/workflows/reusable-examples.yml b/.github/workflows/reusable-examples.yml new file mode 100644 index 000000000000..90a2ea764cbd --- /dev/null +++ b/.github/workflows/reusable-examples.yml @@ -0,0 +1,45 @@ +name: Reusable Examples Workflow + +on: + workflow_call: + inputs: + target-branch: + description: 'Branch to checkout and test (defaults to the calling branch)' + required: false + type: string + default: '' + examples-script: + description: 'Examples script to execute' + required: false + type: string + default: './check-examples.sh' + cache-version: + description: 'Cache version for gem dependencies' + required: false + type: string + default: '' + +jobs: + examples: + runs-on: ubuntu-latest + if: > + (github.event.pull_request.draft == false && + !contains(github.event.pull_request.labels.*.name, 'ci/skip') && + !contains(github.event.pull_request.head.ref, 'datadog-api-spec/test/')) || + github.event_name == 'schedule' + env: + DD_PROFILING_NO_EXTENSION: true + steps: + - uses: actions/checkout@v3 + with: + repository: DataDog/datadog-api-client-ruby + ref: ${{ inputs.target-branch || github.ref }} + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: "2.7" + bundler-cache: true + cache-version: ${{ inputs.cache-version }} + - name: Check examples + run: ${{ inputs.examples-script }} + shell: bash \ No newline at end of file diff --git a/.github/workflows/test_integration.yml b/.github/workflows/reusable-integration-test.yml similarity index 58% rename from .github/workflows/test_integration.yml rename to .github/workflows/reusable-integration-test.yml index 7b641a5f04ab..af6d5e6d0217 100644 --- a/.github/workflows/test_integration.yml +++ b/.github/workflows/reusable-integration-test.yml @@ -1,10 +1,12 @@ -name: Run Integration Tests +name: Reusable Integration Test Workflow permissions: contents: read on: pull_request: + branches: + - master types: - opened - reopened @@ -12,10 +14,48 @@ on: - synchronize - labeled - unlabeled - branches: - - master schedule: - cron: "0 2 * * *" + workflow_call: + inputs: + target-branch: + description: 'Branch to checkout and test (defaults to the calling branch)' + required: false + type: string + default: '' + enable-status-reporting: + description: 'Whether to post status checks to datadog-api-spec repo' + required: false + type: boolean + default: false + status-context: + description: 'Context for status checks' + required: false + type: string + default: 'integration' + target-repo: + description: 'Repository to post status to' + required: false + type: string + default: 'datadog-api-spec' + cache-version: + description: 'Cache version for gem dependencies' + required: false + type: string + default: '' + secrets: + PIPELINE_GITHUB_APP_ID: + required: false + PIPELINE_GITHUB_APP_PRIVATE_KEY: + required: false + DD_API_KEY: + required: true + DD_CLIENT_API_KEY: + required: true + DD_CLIENT_APP_KEY: + required: true + SLEEP_AFTER_REQUEST: + required: false concurrency: group: integration-${{ github.head_ref }} @@ -48,17 +88,20 @@ jobs: with: app-id: ${{ secrets.PIPELINE_GITHUB_APP_ID }} private-key: ${{ secrets.PIPELINE_GITHUB_APP_PRIVATE_KEY }} - repositories: datadog-api-spec + repositories: ${{ inputs.target-repo || 'datadog-api-spec' }} - name: Checkout code uses: actions/checkout@v3 + with: + repository: DataDog/datadog-api-client-ruby + ref: ${{ inputs.target-branch || github.ref }} - name: Post pending status check - if: github.event_name == 'pull_request' && contains(github.event.pull_request.head.ref, 'datadog-api-spec/generated/') + if: github.event_name == 'pull_request' && contains(github.event.pull_request.head.ref, 'datadog-api-spec/generated/') && (inputs.enable-status-reporting || github.event_name != 'workflow_call') uses: DataDog/github-actions/post-status-check@v2 with: github-token: ${{ steps.get_token.outputs.token }} - repo: datadog-api-spec + repo: ${{ inputs.target-repo || 'datadog-api-spec' }} status: pending - context: integration + context: ${{ inputs.status-context || 'integration' }} - name: Install system zstd run: | sudo apt-get -y install zstd @@ -68,7 +111,7 @@ jobs: with: ruby-version: "3.2" bundler-cache: true - cache-version: ${{ secrets.CACHE_VERSION }} + cache-version: ${{ inputs.cache-version }} - name: Install deps run: bundle install - name: Run integration tests @@ -84,20 +127,20 @@ jobs: DD_TEST_CLIENT_APP_KEY: ${{ secrets.DD_CLIENT_APP_KEY }} DD_TRACE_ANALYTICS_ENABLED: "true" RECORD: "none" - SLEEP_AFTER_REQUEST: "${{ vars.SLEEP_AFTER_REQUEST }}" + SLEEP_AFTER_REQUEST: ${{ secrets.SLEEP_AFTER_REQUEST || vars.SLEEP_AFTER_REQUEST }} - name: Post failure status check - if: failure() && github.event_name == 'pull_request' && contains(github.event.pull_request.head.ref, 'datadog-api-spec/generated/') + if: failure() && github.event_name == 'pull_request' && contains(github.event.pull_request.head.ref, 'datadog-api-spec/generated/') && (inputs.enable-status-reporting || github.event_name != 'workflow_call') uses: DataDog/github-actions/post-status-check@v2 with: github-token: ${{ steps.get_token.outputs.token }} - repo: datadog-api-spec + repo: ${{ inputs.target-repo || 'datadog-api-spec' }} status: failure - context: integration + context: ${{ inputs.status-context || 'integration' }} - name: Post success status check - if: "!failure() && github.event_name == 'pull_request' && contains(github.event.pull_request.head.ref, 'datadog-api-spec/generated/')" + if: "!failure() && github.event_name == 'pull_request' && contains(github.event.pull_request.head.ref, 'datadog-api-spec/generated/') && (inputs.enable-status-reporting || github.event_name != 'workflow_call')" uses: DataDog/github-actions/post-status-check@v2 with: github-token: ${{ steps.get_token.outputs.token }} - repo: datadog-api-spec + repo: ${{ inputs.target-repo || 'datadog-api-spec' }} status: success - context: integration + context: ${{ inputs.status-context || 'integration' }} \ No newline at end of file diff --git a/.github/workflows/reusable-pre-commit.yml b/.github/workflows/reusable-pre-commit.yml new file mode 100644 index 000000000000..a5f80fd5e46e --- /dev/null +++ b/.github/workflows/reusable-pre-commit.yml @@ -0,0 +1,82 @@ +name: Reusable Pre-commit Workflow + +on: + workflow_call: + inputs: + target-branch: + description: 'Branch to checkout and test (defaults to the calling branch)' + required: false + type: string + default: '' + enable-commit-changes: + description: 'Whether to commit and push pre-commit fixes' + required: false + type: boolean + default: true + secrets: + PIPELINE_GITHUB_APP_ID: + required: false + PIPELINE_GITHUB_APP_PRIVATE_KEY: + required: false + +env: + GIT_AUTHOR_EMAIL: "packages@datadoghq.com" + GIT_AUTHOR_NAME: "ci.datadog-api-spec" + +jobs: + pre-commit: + runs-on: ubuntu-latest + if: > + (github.event.pull_request.draft == false && + !contains(github.event.pull_request.labels.*.name, 'ci/skip') && + !contains(github.event.pull_request.head.ref, 'datadog-api-spec/test/')) || + github.event_name == 'schedule' + steps: + - name: Get GitHub App token + id: get_token + if: inputs.enable-commit-changes + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ secrets.PIPELINE_GITHUB_APP_ID }} + private-key: ${{ secrets.PIPELINE_GITHUB_APP_PRIVATE_KEY }} + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + repository: DataDog/datadog-api-client-ruby + ref: ${{ inputs.target-branch || github.event.pull_request.head.sha || github.ref }} + token: ${{ inputs.enable-commit-changes && steps.get_token.outputs.token || github.token }} + - uses: actions/setup-python@v4 + with: + python-version: '3.11' + - name: Install pre-commit + run: python -m pip install pre-commit + - name: set PY + run: echo "PY=$(python -c 'import platform;print(platform.python_version())')" >> $GITHUB_ENV + - uses: actions/cache@v3 + with: + path: ~/.cache/pre-commit + key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }} + - id: pre_commit + name: Run pre-commit + if: github.event.action != 'closed' && github.event.pull_request.merged != true + run: | + pre-commit run --from-ref "${FROM_REF}" --to-ref "${TO_REF}" --show-diff-on-failure --color=always + env: + FROM_REF: ${{ github.event.pull_request.base.sha }} + TO_REF: ${{ github.event.pull_request.head.sha }} + - name: Commit changes + if: ${{ failure() && inputs.enable-commit-changes }} + run: |- + git add -A + git config user.name "${GIT_AUTHOR_NAME}" + git config user.email "${GIT_AUTHOR_EMAIL}" + git commit -m "pre-commit fixes" + git push origin "HEAD:${HEAD_REF}" + exit 1 + env: + HEAD_REF: ${{ github.event.pull_request.head.ref }} + - id: pre_commit_schedule + name: Run pre-commit in schedule + if: github.event_name == 'schedule' + run: | + pre-commit run --all-files --show-diff-on-failure --color=always \ No newline at end of file diff --git a/.github/workflows/reusable-ruby-test.yml b/.github/workflows/reusable-ruby-test.yml new file mode 100644 index 000000000000..77c270464268 --- /dev/null +++ b/.github/workflows/reusable-ruby-test.yml @@ -0,0 +1,66 @@ +name: Reusable Ruby Testing Workflow + +on: + workflow_call: + inputs: + target-branch: + description: 'Branch to checkout and test (defaults to the calling branch)' + required: false + type: string + default: '' + ruby-versions: + description: 'JSON array of Ruby versions to test against' + required: false + type: string + default: '["2.7", "3.2", "jruby-9.4.12.0"]' + platforms: + description: 'JSON array of platforms to run tests on' + required: false + type: string + default: '["ubuntu-latest"]' + test-script: + description: 'Test script to execute' + required: false + type: string + default: './run-tests.sh' + cache-version: + description: 'Cache version for gem dependencies' + required: false + type: string + default: '' + secrets: + PIPELINE_GITHUB_APP_ID: + required: false + PIPELINE_GITHUB_APP_PRIVATE_KEY: + required: false + DD_API_KEY: + required: false + +jobs: + test: + strategy: + matrix: + ruby-version: ${{ fromJSON(inputs.ruby-versions) }} + platform: ${{ fromJSON(inputs.platforms) }} + runs-on: ${{ matrix.platform }} + if: (github.event.pull_request.draft == false && !contains(github.event.pull_request.labels.*.name, 'ci/skip') && !contains(github.event.pull_request.head.ref, 'datadog-api-spec/test/')) || github.event_name == 'schedule' + env: + BUNDLE_WITHOUT: docs + DD_PROFILING_NO_EXTENSION: true + DD_CIVISIBILITY_AGENTLESS_ENABLED: true + DD_ENV: prod + DD_API_KEY: ${{ secrets.DD_API_KEY }} + steps: + - uses: actions/checkout@v3 + with: + repository: DataDog/datadog-api-client-ruby + ref: ${{ inputs.target-branch || github.ref }} + - name: Set up Ruby ${{ matrix.ruby-version }} + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby-version }} + bundler-cache: true + cache-version: ${{ inputs.cache-version }} + - name: Test + run: ${{ inputs.test-script }} + shell: bash diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6bb516eb8433..762e1b737419 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,103 +20,45 @@ concurrency: jobs: pre-commit: - runs-on: ubuntu-latest if: > (github.event.pull_request.draft == false && !contains(github.event.pull_request.labels.*.name, 'ci/skip') && !contains(github.event.pull_request.head.ref, 'datadog-api-spec/test/')) || github.event_name == 'schedule' - steps: - - name: Get GitHub App token - id: get_token - uses: actions/create-github-app-token@v1 - with: - app-id: ${{ secrets.PIPELINE_GITHUB_APP_ID }} - private-key: ${{ secrets.PIPELINE_GITHUB_APP_PRIVATE_KEY }} - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - ref: ${{ github.event.pull_request.head.sha }} - token: ${{ steps.get_token.outputs.token }} - - uses: actions/setup-python@v4 - with: - python-version: '3.11' - - name: Install pre-commit - run: python -m pip install pre-commit - - name: set PY - run: echo "PY=$(python -c 'import platform;print(platform.python_version())')" >> $GITHUB_ENV - - uses: actions/cache@v3 - with: - path: ~/.cache/pre-commit - key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }} - - id: pre_commit - name: Run pre-commit - if: github.event.action != 'closed' && github.event.pull_request.merged != true - run: | - pre-commit run --from-ref "${FROM_REF}" --to-ref "${TO_REF}" --show-diff-on-failure --color=always - env: - FROM_REF: ${{ github.event.pull_request.base.sha }} - TO_REF: ${{ github.event.pull_request.head.sha }} - - name: Commit changes - if: ${{ failure() }} - run: |- - git add -A - git config user.name "${GIT_AUTHOR_NAME}" - git config user.email "${GIT_AUTHOR_EMAIL}" - git commit -m "pre-commit fixes" - git push origin "HEAD:${HEAD_REF}" - exit 1 - env: - HEAD_REF: ${{ github.event.pull_request.head.ref }} - - id: pre_commit_schedule - name: Run pre-commit in schedule - if: github.event_name == 'schedule' - run: | - pre-commit run --all-files --show-diff-on-failure --color=always + uses: ./.github/workflows/reusable-pre-commit.yml + with: + enable-commit-changes: true + secrets: + PIPELINE_GITHUB_APP_ID: ${{ secrets.PIPELINE_GITHUB_APP_ID }} + PIPELINE_GITHUB_APP_PRIVATE_KEY: ${{ secrets.PIPELINE_GITHUB_APP_PRIVATE_KEY }} test: - strategy: - matrix: - ruby-version: ["2.7", "3.2", "jruby-9.4.12.0"] - platform: [ubuntu-latest] - runs-on: ${{ matrix.platform }} - if: (github.event.pull_request.draft == false && !contains(github.event.pull_request.labels.*.name, 'ci/skip') && !contains(github.event.pull_request.head.ref, 'datadog-api-spec/test/')) || github.event_name == 'schedule' - env: - BUNDLE_WITHOUT: docs - DD_PROFILING_NO_EXTENSION: true - DD_CIVISIBILITY_AGENTLESS_ENABLED: true - DD_ENV: prod + if: > + (github.event.pull_request.draft == false && + !contains(github.event.pull_request.labels.*.name, 'ci/skip') && + !contains(github.event.pull_request.head.ref, 'datadog-api-spec/test/')) || + github.event_name == 'schedule' + uses: ./.github/workflows/reusable-ruby-test.yml + with: + ruby-versions: '["2.7", "3.2", "jruby-9.4.12.0"]' + platforms: '["ubuntu-latest"]' + test-script: './run-tests.sh' + cache-version: ${{ vars.CACHE_VERSION }} + secrets: + PIPELINE_GITHUB_APP_ID: ${{ secrets.PIPELINE_GITHUB_APP_ID }} + PIPELINE_GITHUB_APP_PRIVATE_KEY: ${{ secrets.PIPELINE_GITHUB_APP_PRIVATE_KEY }} DD_API_KEY: ${{ secrets.DD_API_KEY }} - steps: - - uses: actions/checkout@v3 - - name: Set up Ruby ${{ matrix.ruby-version }} - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ matrix.ruby-version }} - bundler-cache: true - # modify repository variable when there are problems with installing gems - cache-version: ${{ vars.CACHE_VERSION }} - - name: Test - run: ./run-tests.sh - shell: bash examples: - runs-on: ubuntu-latest - if: (github.event.pull_request.draft == false && !contains(github.event.pull_request.labels.*.name, 'ci/skip') && !contains(github.event.pull_request.head.ref, 'datadog-api-spec/test/')) || github.event_name == 'schedule' - env: - DD_PROFILING_NO_EXTENSION: true - steps: - - uses: actions/checkout@v3 - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: "2.7" - bundler-cache: true - # modify repository variable when there are problems with installing gems - cache-version: ${{ vars.CACHE_VERSION }} - - name: Check examples - run: ./check-examples.sh - shell: bash + if: > + (github.event.pull_request.draft == false && + !contains(github.event.pull_request.labels.*.name, 'ci/skip') && + !contains(github.event.pull_request.head.ref, 'datadog-api-spec/test/')) || + github.event_name == 'schedule' + uses: ./.github/workflows/reusable-examples.yml + with: + examples-script: './check-examples.sh' + cache-version: ${{ vars.CACHE_VERSION }} report: runs-on: ubuntu-latest @@ -133,10 +75,10 @@ jobs: app-id: ${{ secrets.PIPELINE_GITHUB_APP_ID }} private-key: ${{ secrets.PIPELINE_GITHUB_APP_PRIVATE_KEY }} repositories: datadog-api-spec - - name: Post status 3heck + - name: Post status check uses: DataDog/github-actions/post-status-check@v2 with: github-token: ${{ steps.get_token.outputs.token }} repo: datadog-api-spec - status: ${{ (needs.test.result == 'cancelled' || needs.examples.result == 'cancelled') && 'pending' || needs.test.result == 'success' && needs.examples.result == 'success' && 'success' || 'failure' }} + status: ${{ (needs.test.result == 'cancelled' || needs.examples.result == 'cancelled') && 'pending' || (needs.test.result == 'success' && needs.examples.result == 'success') && 'success' || 'failure' }} context: master/unit