diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 0a91f38..87dcabb 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -36,10 +36,20 @@ jobs: validate_orb: timeout-minutes: 5 runs-on: ubuntu-22.04 + outputs: + job_id: ${{ steps.get-job-id.outputs.job_id }} steps: - name: Checkout 🛎️ uses: actions/checkout@v4.1.7 + - name: Setup Python 🔧 + uses: actions/setup-python@v5.3.0 + with: + python-version: ">=3.12" + + - name: Install CLI + run: pip install mergify-cli + - name: Start mockServer with expectation initializer run: | docker compose up -d @@ -48,23 +58,38 @@ jobs: - name: Test Orb upload script id: gigid - run: | - export FAKE_VALID_TOKEN=fake-valid-token - bash src/scripts/upload.sh >> "$GITHUB_OUTPUT" env: - REPO_URL: ${{ github.server_url }}/${{ github.repository }} - TOKEN: FAKE_VALID_TOKEN + MERGIFY_API_URL: http://localhost:1080 + MERGIFY_TOKEN: fake-valid-token + FILES: zfixtures/junit_example.xml + # force fake test environment + CIRCLECI: true + # GITHUB_ACTIONS: false CIRCLE_JOB: test + CIRCLE_REPOSITORY_URL: ${{ github.event.repository.html_url }} CIRCLE_SHA1: 948da8c01b17ac2164039f3150221d5cfcae7ecc - FILES: zfixtures/junit_example.xml - MERGIFY_API_SERVER: http://localhost:1080 - - - name: Check GIGID - env: - CI_ISSUE_GIGID: ${{ steps.gigid.outputs.CI_ISSUE_GIGID }} run: | - set -e - test "$CI_ISSUE_GIGID" = "1234azertyuiop" + export GITHUB_ACTIONS=false + bash src/scripts/upload.sh + + - name: Get job ID + id: get-job-id + uses: actions/github-script@v7 + with: + script: | + const { data } = await github.rest.actions.listJobsForWorkflowRun({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: context.runId + }); + // Looks for exact match + let job = data.jobs.find( + (j) => j.name === context.job + ) + if (!job) { + core.error("current job not found"); + } + core.setOutput("job_id", String(job.id)); - name: Mockserver logs if: always() @@ -77,3 +102,26 @@ jobs: run: | circleci orb pack src > orb.yml circleci orb validate orb.yml + + test-annotations: + needs: validate_orb + timeout-minutes: 5 + runs-on: ubuntu-latest + steps: + - name: Check GIGID + uses: actions/github-script@v7 + with: + script: | + const annotations = await github.rest.checks.listAnnotations({ + owner: context.repo.owner, + repo: context.repo.repo, + check_run_id: ${{ needs.validate_orb.outputs.job_id }}, + }); + for (const annotation of annotations.data) { + if (annotation.message.trim() === "CI_ISSUE_GIGID=1234azertyuiop") { + core.info(`Annotations found: ${annotation.message}`) + return + } + } + console.log(annotations) + throw new Error("Annotations not found") diff --git a/src/commands/upload.yml b/src/commands/upload.yml old mode 100755 new mode 100644 index d71fb40..be42690 --- a/src/commands/upload.yml +++ b/src/commands/upload.yml @@ -1,27 +1,36 @@ -description: Upload the XML report +description: Upload the Junit XML report + parameters: token: type: env_var_name - description: CI Issues Application Key - default: MERGIFY_CI_ISSUES_TOKEN - repository_url: - description: | - URL of the repository (should provide pipeline.trigger_parameters.github_app.repo_url) - type: string + description: Mergify Application Key + default: MERGIFY_TOKEN report_paths: description: Paths of the XML files to upload type: string - mergify_api_server: + mergify_api_url: description: URL of the Mergify API type: string - default: https://api.mergify.com/v1 + default: https://api.mergify.com + steps: + - run: + name: Install Python + when: always + command: | + sudo apt-get update + sudo apt-get install -y python3 + + - run: + name: Install mergify-cli + when: always + command: pip install mergify-cli + - run: name: Uploading the reports to Mergify CI Issues + when: always environment: - TOKEN: <> - REPO_URL: <> + MERGIFY_API_URL: <> + MERGIFY_TOKEN: <> FILES: <> - MERGIFY_API_SERVER: <> - when: always command: <> diff --git a/src/examples/example.yml b/src/examples/example.yml index 2162062..362875b 100755 --- a/src/examples/example.yml +++ b/src/examples/example.yml @@ -23,11 +23,7 @@ usage: mkdir test_results poetry run pytest -vv --junitxml=test_results/report.xml - mergifyio/upload: - token: MERGIFY_CI_ISSUES_TOKEN - repository_url: <> report_paths: test_results/report.xml - - store_test_results: - path: test_results workflows: continuous_integration: diff --git a/src/scripts/upload.sh b/src/scripts/upload.sh index fdc569c..2b2c57c 100644 --- a/src/scripts/upload.sh +++ b/src/scripts/upload.sh @@ -1,35 +1,5 @@ #!/bin/bash -set -x +set -e -x -if [[ $REPO_URL =~ ^https:\/\/github\.com\/([a-zA-Z0-9._-]+)\/([a-zA-Z0-9._-]+)$ ]]; then - REPO_FULL_NAME=${BASH_REMATCH[1]}/${BASH_REMATCH[2]} -else - echo "Invalid repository URL: $REPO_URL" - exit 1 -fi - -# Check if FILES and TOKEN are set and not empty -if [ -z "${FILES}" ]; then - echo "report_paths is not set or is empty" - exit 1 -fi -if [ -z "${!TOKEN}" ]; then - echo "${!TOKEN} is not set or is empty" - exit 1 -fi - -# TODO: support multiple files -curl -X POST \ - -H "Authorization: bearer ${!TOKEN}" \ - -F name=${CIRCLE_JOB} \ - -F provider=circleci \ - -F head_sha=${CIRCLE_SHA1} \ - -F files=@${FILES} \ - -o result.json \ - ${MERGIFY_API_SERVER}/repos/${REPO_FULL_NAME}/ci_issues_upload \ - -GIGID=$(cat result.json | jq -r .gigid) -echo "::notice title=CI Issues report::CI_ISSUE_GIGID=$GIGID" - -echo "CI_ISSUE_GIGID=$GIGID" +mergify ci junit-upload "${FILES}" diff --git a/zfixtures/expectationInitializer.json b/zfixtures/expectationInitializer.json index e656cf5..79871f2 100644 --- a/zfixtures/expectationInitializer.json +++ b/zfixtures/expectationInitializer.json @@ -2,13 +2,13 @@ { "httpRequest": { "method": "POST", - "path": "/repos/Mergifyio/circleci-ci-issues/ci_issues_upload", + "path": "/v1/repos/Mergifyio/circleci-ci-issues/ci_issues_upload", "headers": { - "Authorization": "bearer fake-valid-token" + "Authorization": "Bearer fake-valid-token" }, "body": { "type": "REGEX", - "regex": ".*Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\\r\\ntest\\r\\n.*\\r\\nContent-Disposition: form-data; name=\\\"provider\\\"\\r\\n\\r\\ncircleci\\r\\n.*\\r\\nContent-Disposition: form-data; name=\\\"head_sha\\\"\\r\\n\\r\\n948da8c01b17ac2164039f3150221d5cfcae7ecc\\r\\n.*\\r\\nContent-Disposition: form-data; name=\\\"files\\\"; filename=\\\"junit_example.xml\\\"\\r\\nContent-Type: application/xml\\r\\n\\r\\n.*" + "regex": ".*Content-Disposition: form-data; name=\\\"head_sha\\\"\\r\\n\\r\\n948da8c01b17ac2164039f3150221d5cfcae7ecc\\r\\n.*\\r\\nContent-Disposition: form-data; name=\\\"name\\\"\\r\\n\\r\\ntest\\r\\n.*\\r\\nContent-Disposition: form-data; name=\\\"provider\\\"\\r\\n\\r\\ncircleci\\r\\n.*\\r\\nContent-Disposition: form-data; name=\\\"files\\\"; filename=\\\"junit_example.xml\\\"\\r\\nContent-Type: application/xml\\r\\n\\r\\n.*" } }, "httpResponse": {