From 84386928aa9664e269abadffe70630a69c9ca956 Mon Sep 17 00:00:00 2001 From: Rodrigo Nascimento Date: Wed, 31 Dec 2025 17:09:01 -0300 Subject: [PATCH] fix: CI for external PRs (#38030) --- .github/actions/build-docker/action.yml | 52 ++++++++++---- .github/workflows/ci-test-e2e.yml | 38 ++++++++--- .github/workflows/ci.yml | 91 +++++++++++++++---------- 3 files changed, 122 insertions(+), 59 deletions(-) diff --git a/.github/actions/build-docker/action.yml b/.github/actions/build-docker/action.yml index 5100528ac7ae0..12bd993c665da 100644 --- a/.github/actions/build-docker/action.yml +++ b/.github/actions/build-docker/action.yml @@ -119,25 +119,53 @@ runs: echo "Contents of /tmp/meta.json:" cat /tmp/meta.json - SERVICE_SUFFIX=${{ inputs.service == 'rocketchat' && inputs.type == 'coverage' && (github.event_name == 'release' || github.ref == 'refs/heads/develop') && '-cov' || '' }} + if [[ "${{ inputs.publish-image }}" == 'true' ]]; then + SERVICE_SUFFIX=${{ inputs.service == 'rocketchat' && inputs.type == 'coverage' && (github.event_name == 'release' || github.ref == 'refs/heads/develop') && '-cov' || '' }} + + mkdir -p /tmp/manifests/${{ inputs.service }}${SERVICE_SUFFIX}/${{ inputs.arch }} - mkdir -p /tmp/manifests/${{ inputs.service }}${SERVICE_SUFFIX}/${{ inputs.arch }} + # Get digest and image info + DIGEST=$(jq -r '.["${{ inputs.service }}"].["containerimage.digest"]' "/tmp/meta.json") + IMAGE_NO_TAG=$(echo "$IMAGE" | sed 's/:.*$//') + FULL_IMAGE="${IMAGE_NO_TAG}@${DIGEST}" - # Get digest and image info - DIGEST=$(jq -r '.["${{ inputs.service }}"].["containerimage.digest"]' "/tmp/meta.json") - IMAGE_NO_TAG=$(echo "$IMAGE" | sed 's/:.*$//') - FULL_IMAGE="${IMAGE_NO_TAG}@${DIGEST}" + echo "Inspecting image: $FULL_IMAGE" - echo "Inspecting image: $FULL_IMAGE" + # Inspect the image and save complete manifest with sizes (using -v for verbose) + docker manifest inspect -v "$FULL_IMAGE" > "/tmp/manifests/${{ inputs.service }}${SERVICE_SUFFIX}/${{ inputs.arch }}/manifest.json" + + echo "Saved manifest to /tmp/manifests/${{ inputs.service }}${SERVICE_SUFFIX}/${{ inputs.arch }}/manifest.json" + cat "/tmp/manifests/${{ inputs.service }}${SERVICE_SUFFIX}/${{ inputs.arch }}/manifest.json" | jq '.' + fi - # Inspect the image and save complete manifest with sizes (using -v for verbose) - docker manifest inspect -v "$FULL_IMAGE" > "/tmp/manifests/${{ inputs.service }}${SERVICE_SUFFIX}/${{ inputs.arch }}/manifest.json" + - name: Save Docker image as artifact + if: inputs.publish-image == 'false' && inputs.arch == 'amd64' + shell: bash + run: | + set -o xtrace - echo "Saved manifest to /tmp/manifests/${{ inputs.service }}${SERVICE_SUFFIX}/${{ inputs.arch }}/manifest.json" - cat "/tmp/manifests/${{ inputs.service }}${SERVICE_SUFFIX}/${{ inputs.arch }}/manifest.json" | jq '.' + # Get image name from docker-compose-ci.yml + IMAGE=$(docker compose -f docker-compose-ci.yml config --format json 2>/dev/null | jq -r --arg s "${{ inputs.service }}" '.services[$s].image') + + # Create directory for image archives + mkdir -p /tmp/docker-images + + # Save the image to a tar file + docker save "${IMAGE}" -o "/tmp/docker-images/${{ inputs.service }}-${{ inputs.arch }}-${{ inputs.type }}.tar" + + echo "Saved image to /tmp/docker-images/${{ inputs.service }}-${{ inputs.arch }}-${{ inputs.type }}.tar" + ls -lh /tmp/docker-images/ + + - name: Upload Docker image artifact + if: inputs.publish-image == 'false' && inputs.arch == 'amd64' + uses: actions/upload-artifact@v4 + with: + name: docker-image-${{ inputs.service }}-${{ inputs.arch }}-${{ inputs.type }} + path: /tmp/docker-images/${{ inputs.service }}-${{ inputs.arch }}-${{ inputs.type }}.tar + retention-days: 1 - uses: actions/upload-artifact@v4 - if: inputs.publish-image == 'true' + if: inputs.publish-image == 'true' && inputs.arch == 'amd64' with: name: manifests-${{ inputs.service }}-${{ inputs.arch }}-${{ inputs.type }} path: /tmp/manifests diff --git a/.github/workflows/ci-test-e2e.yml b/.github/workflows/ci-test-e2e.yml index 828a50aaa4040..4b6bb6ebffb19 100644 --- a/.github/workflows/ci-test-e2e.yml +++ b/.github/workflows/ci-test-e2e.yml @@ -68,7 +68,7 @@ env: MONGO_URL: mongodb://localhost:27017/rocketchat?replicaSet=rs0&directConnection=true TOOL_NODE_FLAGS: ${{ vars.TOOL_NODE_FLAGS }} LOWERCASE_REPOSITORY: ${{ inputs.lowercase-repo }} - DOCKER_TAG: ${{ inputs.gh-docker-tag }} + DOCKER_TAG: ${{ inputs.gh-docker-tag }}-amd64 jobs: test: @@ -139,17 +139,33 @@ jobs: run: | tar -xzf /tmp/RocketChat-packages-build.tar.gz -C . - # if we are testing a PR from a fork, we need to build the docker image at this point - - uses: ./.github/actions/build-docker - if: github.event_name == 'pull_request' && (github.event.pull_request.head.repo.full_name != github.repository || github.actor == 'dependabot[bot]') + # Download Docker images from build artifacts + - name: Download Docker images + uses: actions/download-artifact@v7 + if: github.event.pull_request.head.repo.full_name != github.repository && github.event_name != 'release' && github.ref != 'refs/heads/develop' with: - CR_USER: ${{ secrets.CR_USER }} - CR_PAT: ${{ secrets.CR_PAT }} - # the same reason we need to rebuild the docker image at this point is the reason we dont want to publish it - publish-image: false - arch: amd64 - service: 'rocketchat' - type: 'coverage' + pattern: ${{ inputs.release == 'ce' && 'docker-image-rocketchat-amd64-coverage' || 'docker-image-*-amd64-coverage' }} + path: /tmp/docker-images + merge-multiple: true + + # Load Docker images + - name: Load Docker images + if: github.event.pull_request.head.repo.full_name != github.repository && github.event_name != 'release' && github.ref != 'refs/heads/develop' + shell: bash + run: | + set -o xtrace + + # Load all downloaded images + for image_file in /tmp/docker-images/*.tar; do + if [ -f "$image_file" ]; then + echo "Loading image from $image_file" + docker load -i "$image_file" + rm "$image_file" + fi + done + + # List loaded images + docker images - name: Set DEBUG_LOG_LEVEL (debug enabled) if: runner.debug == '1' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7c077b50b820f..72a39d96ad50c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -314,7 +314,7 @@ jobs: # we only build and publish the actual docker images if not a PR from a fork - name: Image ${{ matrix.service[0] }} uses: ./.github/actions/build-docker - if: (github.event.pull_request.head.repo.full_name == github.repository || github.event_name == 'release' || github.ref == 'refs/heads/develop') && github.actor != 'dependabot[bot]' + if: github.actor != 'dependabot[bot]' env: # add suffix for the extra images with coverage if building for production DOCKER_TAG_SUFFIX_ROCKETCHAT: ${{ matrix.type == 'coverage' && (github.event_name == 'release' || github.ref == 'refs/heads/develop') && '-cov' || '' }} @@ -325,10 +325,11 @@ jobs: arch: ${{ matrix.arch }} service: ${{ matrix.service[0] }} type: ${{ matrix.type }} + publish-image: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.event_name == 'release' || github.ref == 'refs/heads/develop' }} - name: Image ${{ matrix.service[1] || '"skipped"' }} uses: ./.github/actions/build-docker - if: matrix.service[1] && (github.event.pull_request.head.repo.full_name == github.repository || github.event_name == 'release' || github.ref == 'refs/heads/develop') && github.actor != 'dependabot[bot]' + if: matrix.service[1] && github.actor != 'dependabot[bot]' env: DOCKER_TAG_SUFFIX_ROCKETCHAT: ${{ matrix.type == 'coverage' && '-cov' || '' }} with: @@ -338,11 +339,12 @@ jobs: arch: ${{ matrix.arch }} service: ${{ matrix.service[1] }} type: ${{ matrix.type }} + publish-image: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.event_name == 'release' || github.ref == 'refs/heads/develop' }} setup-docker: false - name: Image ${{ matrix.service[2] || '"skipped"' }} uses: ./.github/actions/build-docker - if: matrix.service[2] && (github.event.pull_request.head.repo.full_name == github.repository || github.event_name == 'release' || github.ref == 'refs/heads/develop') && github.actor != 'dependabot[bot]' + if: matrix.service[2] && github.actor != 'dependabot[bot]' env: DOCKER_TAG_SUFFIX_ROCKETCHAT: ${{ matrix.type == 'coverage' && '-cov' || '' }} with: @@ -352,11 +354,12 @@ jobs: arch: ${{ matrix.arch }} service: ${{ matrix.service[2] }} type: ${{ matrix.type }} + publish-image: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.event_name == 'release' || github.ref == 'refs/heads/develop' }} setup-docker: false - name: Image ${{ matrix.service[3] || '"skipped"' }} uses: ./.github/actions/build-docker - if: matrix.service[3] && (github.event.pull_request.head.repo.full_name == github.repository || github.event_name == 'release' || github.ref == 'refs/heads/develop') && github.actor != 'dependabot[bot]' + if: matrix.service[3] && github.actor != 'dependabot[bot]' env: DOCKER_TAG_SUFFIX_ROCKETCHAT: ${{ matrix.type == 'coverage' && '-cov' || '' }} with: @@ -366,6 +369,7 @@ jobs: arch: ${{ matrix.arch }} service: ${{ matrix.service[3] }} type: ${{ matrix.type }} + publish-image: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.event_name == 'release' || github.ref == 'refs/heads/develop' }} setup-docker: false build-gh-docker-publish: @@ -452,6 +456,7 @@ jobs: - name: Track Docker image sizes uses: ./.github/actions/docker-image-size-tracker + if: github.actor != 'dependabot[bot]' && github.event.pull_request.head.repo.full_name == github.repository with: github-token: ${{ secrets.GITHUB_TOKEN }} registry: ghcr.io @@ -579,39 +584,10 @@ jobs: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} REPORTER_JIRA_ROCKETCHAT_API_KEY: ${{ secrets.REPORTER_JIRA_ROCKETCHAT_API_KEY }} - test-ui-ee-watcher: - name: 🔨 Test UI (EE) - needs: [checks, build-gh-docker-publish, release-versions] - - uses: ./.github/workflows/ci-test-e2e.yml - with: - type: ui - release: ee - transporter: 'nats://nats:4222' - enterprise-license: ${{ needs.release-versions.outputs.enterprise-license }} - shard: '[1, 2, 3, 4, 5]' - total-shard: 5 - mongodb-version: "['8.2']" - coverage: '8.2' - node-version: ${{ needs.release-versions.outputs.node-version }} - deno-version: ${{ needs.release-versions.outputs.deno-version }} - lowercase-repo: ${{ needs.release-versions.outputs.lowercase-repo }} - gh-docker-tag: ${{ needs.release-versions.outputs.gh-docker-tag }} - retries: ${{ (github.event_name == 'release' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/master') && 2 || 0 }} - db-watcher-disabled: 'false' - secrets: - CR_USER: ${{ secrets.CR_USER }} - CR_PAT: ${{ secrets.CR_PAT }} - QASE_API_TOKEN: ${{ secrets.QASE_API_TOKEN }} - REPORTER_ROCKETCHAT_API_KEY: ${{ secrets.REPORTER_ROCKETCHAT_API_KEY }} - REPORTER_ROCKETCHAT_URL: ${{ secrets.REPORTER_ROCKETCHAT_URL }} - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - REPORTER_JIRA_ROCKETCHAT_API_KEY: ${{ secrets.REPORTER_JIRA_ROCKETCHAT_API_KEY }} - test-federation-matrix: name: 🔨 Test Federation Matrix needs: [checks, build-gh-docker-publish, packages-build, release-versions] - runs-on: ubuntu-24.04-arm + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v5 @@ -649,14 +625,57 @@ jobs: sudo -- sh -c "echo '127.0.0.1 hs1' >> /etc/hosts" sudo -- sh -c "echo '127.0.0.1 rc1' >> /etc/hosts" + # Download Docker images from build artifacts + - name: Download Docker images + uses: actions/download-artifact@v7 + if: github.event.pull_request.head.repo.full_name != github.repository && github.event_name != 'release' && github.ref != 'refs/heads/develop' + with: + pattern: 'docker-image-rocketchat-amd64-coverage' + path: /tmp/docker-images + merge-multiple: true + + # Load Docker images + - name: Load Docker images + if: github.event.pull_request.head.repo.full_name != github.repository && github.event_name != 'release' && github.ref != 'refs/heads/develop' + shell: bash + run: | + set -o xtrace + + # Load all downloaded images + for image_file in /tmp/docker-images/*.tar; do + if [ -f "$image_file" ]; then + echo "Loading image from $image_file" + docker load -i "$image_file" + rm "$image_file" + fi + done + + # List loaded images + docker images + - name: Run federation integration tests with pre-built image working-directory: ./ee/packages/federation-matrix env: - ROCKETCHAT_IMAGE: ghcr.io/${{ needs.release-versions.outputs.lowercase-repo }}/rocket.chat:${{ needs.release-versions.outputs.gh-docker-tag }} - ENTERPRISE_LICENSE_RC1: ${{ secrets.ENTERPRISE_LICENSE_RC1 }} + ROCKETCHAT_IMAGE: ghcr.io/${{ needs.release-versions.outputs.lowercase-repo }}/rocket.chat:${{ needs.release-versions.outputs.gh-docker-tag }}-amd64 + ENTERPRISE_LICENSE_RC1: ZEuDWcAxkdBZ0iOzn+JIi7Ri0GKPR43hTueeqEEeTjJhzhp1jM7+fA9LiT3aCzU/oJwudwWLFAwqjrtR13axza+Us6lHuAMdfut/1Z6upRWdSgose1LfDP9Nzce6xOVbO3InQonwTQVQJotlYEGRjiry7jn68TSIKhmjMgC6SVYt6v+syEKRgj+r2oT0xNkurQYGGG1AIYHDqGWa1cX0FVd1ddOKU/DNuCJQxH8Rz5aJC2grIKMIzmRVHfBDJAipeTDl6VI28VM5ExEl3w8zDlUk8wCxXawXGCht0A7jZGCd4IQLDNZs/3Zv+nHC4lcDVzjDu+o17vUIEad4m+nhZgGTNlHqkrH3cqEEEPa3bSh8GKBzLmKHB+i0H3dweT9iqGwz56Nue7twyt5yuGq6qYdtrEx0pEKjystU15DUiQxDPqkBL8yRkp5WScsvJIlhiY+4tU6yKI/GAYtU0g+fCYzjzwxXc7tLg5NeY9kiRMdQ+jRytl3ztHGiv5ERhjQKT9ZpUWiCSCmdr8L3njfLLW1e5/AKmXpg00D6HfJvI30xDcoJwmWnCzFvd7KlSbVwNVBlD6KE9+0j6GV1h0JEml1YrpXUxbpEBz5ALdLn2iVPQ3MT5RODRI5yffSX9ikFkwcH360ewU6Zp63WKRkHyfnzE+tsYe96XdaMZowe7Lw= QASE_TESTOPS_JEST_API_TOKEN: ${{ secrets.QASE_TESTOPS_JEST_API_TOKEN }} run: yarn test:integration --image "${ROCKETCHAT_IMAGE}" + - name: Show rc server logs if tests failed + if: failure() + working-directory: ./ee/packages/federation-matrix + run: docker compose -f docker-compose.test.yml logs rc1-prebuilt + + - name: Show hs server logs if tests failed + if: failure() + working-directory: ./ee/packages/federation-matrix + run: docker compose -f docker-compose.test.yml logs hs1 + + - name: Show mongo logs if tests failed + if: failure() + working-directory: ./ee/packages/federation-matrix + run: docker compose -f docker-compose.test.yml logs mongo + report-coverage: name: 📊 Report Coverage runs-on: ubuntu-24.04