diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 31b27cda7..287dad302 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -48,7 +48,6 @@ on: env: artifact_retention_days_for_image: 7 - artifact_retention_days_for_logs: 60 jobs: @@ -94,12 +93,6 @@ jobs: deps="$(<<< $images ./.scripts/images-deps)" <<< $deps jq echo "deps=$deps" >> $GITHUB_OUTPUT - - name: Additional Tests - id: tests - run: | - tests="$(<<< $images ./.scripts/images-additional-tests)" - <<< $tests jq - echo "additional-tests=$tests" >> $GITHUB_OUTPUT load: needs: [setup] @@ -312,126 +305,12 @@ jobs: retention-days: ${{ env.artifact_retention_days_for_image }} test: + if: inputs.test + name: 6 test needs: [setup, build] - if: always() && !failure() && !cancelled() && (github.event_name != 'workflow_call' || inputs.test == true) - strategy: - matrix: - image: ${{ fromJSON(needs.setup.outputs.images) }} - arch: ${{ fromJSON(inputs.archs) }} - network: ["local"] - enable: ["core","rpc","core,rpc,horizon"] - options: [""] - include: ${{ fromJSON(needs.setup.outputs.additional-tests) }} - fail-fast: false - name: 6 test (${{ matrix.image.tag }}, ${{ matrix.arch }}, ${{ matrix.network }}, ${{ matrix.enable }} ${{ matrix.options || '' }}, ${{ matrix.image.tests.continue-on-error && 'continue-on-error' || ''}}) - runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} - continue-on-error: ${{ matrix.image.tests.continue-on-error || false }} - steps: - - name: Free up disk space - if: matrix.network == 'pubnet' - run: | - sudo rm -rf /usr/share/dotnet - sudo rm -rf /usr/local/lib/android - sudo rm -rf /opt/ghc - sudo rm -rf /opt/hostedtoolcache/CodeQL - df -h - - uses: actions/checkout@v2 - with: - repository: ${{ inputs.repo }} - ref: ${{ needs.setup.outputs.sha }} - - name: Download Quickstart Image - uses: actions/download-artifact@v4 - with: - name: image-quickstart-${{ matrix.image.tag }}-${{ matrix.arch }}.tar - path: /tmp/ - - name: Load Quickstart Image - run: docker load -i /tmp/image - - name: Prepare Logs Directory - run: mkdir -p logs - - name: Run Quickstart Image - run: > - docker run - --platform linux/${{ matrix.arch }} - -d - -p - "8000:8000" - -p "11626:11626" - --name stellar - quickstart:${{ matrix.image.tag }}-${{ matrix.arch }} - --${{ matrix.network }} - --enable ${{ matrix.enable }} - ${{ matrix.options }} - - name: Set up Go - uses: actions/setup-go@v2 - with: - go-version: ^1 - - name: Sleep until supervisor is up - run: sleep 10 - - name: Calculate timeout - id: timeout - run: echo "minutes=$((${{ github.run_attempt }} * 2))" >> $GITHUB_OUTPUT - - name: Run core test - if: ${{ contains(matrix.enable, 'core') }} - timeout-minutes: ${{ fromJSON(steps.timeout.outputs.minutes) }} - run: | - docker logs stellar -f & - echo "supervisorctl tail -f stellar-core" | docker exec -i stellar sh & - go run tests/test_core.go - curl http://localhost:11626/info - - name: Run horizon up test - if: ${{ contains(matrix.enable, 'horizon') }} - timeout-minutes: ${{ fromJSON(steps.timeout.outputs.minutes) }} - run: | - docker logs stellar -f & - echo "supervisorctl tail -f horizon" | docker exec -i stellar sh & - go run tests/test_horizon_up.go - curl http://localhost:8000 - - name: Run horizon core up test - if: ${{ contains(matrix.enable, 'horizon') && matrix.network != 'pubnet' }} - timeout-minutes: ${{ fromJSON(steps.timeout.outputs.minutes) }} - run: | - docker logs stellar -f & - echo "supervisorctl tail -f horizon" | docker exec -i stellar sh & - go run tests/test_horizon_core_up.go - curl http://localhost:8000 - - name: Run horizon ingesting test - if: ${{ contains(matrix.enable, 'horizon') && matrix.network != 'pubnet' }} - timeout-minutes: ${{ fromJSON(steps.timeout.outputs.minutes) }} - run: | - docker logs stellar -f & - echo "supervisorctl tail -f stellar-core" | docker exec -i stellar sh & - echo "supervisorctl tail -f horizon" | docker exec -i stellar sh & - go run tests/test_horizon_ingesting.go - curl http://localhost:8000 - - name: Run friendbot test - if: ${{ contains(matrix.enable, 'horizon') && matrix.network == 'local' }} - timeout-minutes: ${{ fromJSON(steps.timeout.outputs.minutes) }} - run: | - docker logs stellar -f & - echo "supervisorctl tail -f friendbot" | docker exec -i stellar sh & - echo "supervisorctl tail -f horizon" | docker exec -i stellar sh & - go run tests/test_friendbot.go - - name: Run stellar rpc up test - if: ${{ contains(matrix.enable, 'rpc') }} - timeout-minutes: ${{ fromJSON(steps.timeout.outputs.minutes) }} - run: | - docker logs stellar -f & - echo "supervisorctl tail -f stellar-rpc" | docker exec -i stellar sh & - go run tests/test_stellar_rpc_up.go - - name: Run stellar rpc healthy test - if: ${{ contains(matrix.enable, 'rpc') && matrix.network != 'pubnet' }} - timeout-minutes: ${{ fromJSON(steps.timeout.outputs.minutes) }} - run: | - docker logs stellar -f & - echo "supervisorctl tail -f stellar-rpc" | docker exec -i stellar sh & - go run tests/test_stellar_rpc_healthy.go - - name: Prepare Test Logs - if: always() - run: docker cp stellar:/var/log logs - - name: Upload Test Logs - if: always() - uses: actions/upload-artifact@v4 - with: - name: logs-${{ matrix.image.tag }}-${{ matrix.arch }}-test-${{ strategy.job-index }} - path: logs - retention-days: ${{ env.artifact_retention_days_for_logs }} + uses: ./.github/workflows/test.yml + with: + repo: ${{ inputs.repo }} + ref: ${{ needs.setup.outputs.sha }} + images: ${{ inputs.images }} + archs: ${{ inputs.archs }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 460553bbd..de2462230 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: complete: if: always() name: complete - needs: [build, action-using-artifact, push, action-using-registry] + needs: [build, test, action-using-artifact, push, action-using-registry] runs-on: ubuntu-latest steps: - if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') @@ -44,6 +44,7 @@ jobs: name: 1 setup runs-on: ubuntu-latest outputs: + sha: ${{ steps.sha.outputs.sha }} tag-prefix: ${{ steps.tag-prefix.outputs.tag-prefix }} tag-alias-prefix: ${{ steps.tag-prefix.outputs.tag-alias-prefix }} images: ${{ steps.images.outputs.images }} @@ -54,6 +55,10 @@ jobs: with: fetch-depth: 0 # Get all history for the sha count below. ref: ${{ github.event.pull_request.head.sha || github.sha }} + - name: Sha + id: sha + run: | + echo "sha=$(git rev-parse HEAD)" | tee -a $GITHUB_OUTPUT - name: Tag Prefix id: tag-prefix run: | @@ -88,24 +93,34 @@ jobs: needs: setup uses: ./.github/workflows/build.yml with: - ref: ${{ github.event.pull_request.head.sha || github.sha }} + ref: ${{ needs.setup.outputs.sha }} + images: ${{ needs.setup.outputs.images }} + archs: ${{ needs.setup.outputs.archs }} + test: false # do not run tests as part of build, tests run in parallel with push + + test: + name: 3 test + needs: [setup, build] + uses: ./.github/workflows/test.yml + with: + ref: ${{ needs.setup.outputs.sha }} images: ${{ needs.setup.outputs.images }} archs: ${{ needs.setup.outputs.archs }} action-using-artifact: needs: [setup, build] - name: 3 test action artifact + name: 4 test action artifact uses: ./.github/workflows/action-test.yml with: artifact: image-quickstart-${{ fromJSON(needs.setup.outputs.tags)[0] }}-${{ fromJSON(needs.setup.outputs.archs)[0] }}.tar tag: ${{ fromJSON(needs.setup.outputs.tags)[0] }}-${{ fromJSON(needs.setup.outputs.archs)[0] }} push: - name: 4 push + name: 5 push needs: [setup, build] uses: ./.github/workflows/push.yml with: - sha: ${{ github.event.pull_request.head.sha || github.sha }} + sha: ${{ needs.setup.outputs.sha }} tags: ${{ needs.setup.outputs.tags }} archs: ${{ needs.setup.outputs.archs }} tag-prefix: ${{ needs.setup.outputs.tag-prefix }} @@ -118,7 +133,7 @@ jobs: action-using-registry: needs: [setup, push] - name: 5 test action registry + name: 6 test action registry uses: ./.github/workflows/action-test.yml with: tag: ${{ needs.setup.outputs.tag-prefix }}${{ fromJSON(needs.setup.outputs.tags)[0] }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 000000000..03a6bb617 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,183 @@ +name: Test + +# This workflow tests multiple quickstart images that have been built with the +# build.yml. This workflow and the build.yml workflow are coupled, and this +# workflow makes assumptions about what artifact names the images hae been +# saved under. This workflow is not intended to be called by third parties. + +on: + workflow_call: + inputs: + repo: + description: "Quickstart repo where quickstart is hosted" + type: "string" + default: "stellar/quickstart" + ref: + description: "Quickstart ref to load tests from (sha, branch, tag)" + type: "string" + default: "main" + images: + description: "A custom image.json (a single image from the same format as images.json), if not provided the full images.json is run" + type: "string" + required: true + archs: + description: 'Architectures to build for as an array (e.g. ["amd64", "arm64"])' + type: "string" + required: true + +env: + artifact_retention_days_for_logs: 60 + +jobs: + + complete: + if: always() + name: complete + needs: [setup, test] + runs-on: ubuntu-latest + steps: + - if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') + run: exit 1 + + setup: + name: 1 setup + runs-on: ubuntu-latest + outputs: + additional-tests: ${{ steps.tests.outputs.additional-tests }} + steps: + - uses: actions/checkout@v2 + with: + repository: ${{ inputs.repo }} + ref: ${{ inputs.ref }} + - name: Additional Tests + id: tests + env: + images: ${{ inputs.images }} + run: | + tests="$(<<< $images ./.scripts/images-additional-tests)" + <<< $tests jq + echo "additional-tests=$tests" >> $GITHUB_OUTPUT + + test: + needs: setup + strategy: + matrix: + image: ${{ fromJSON(inputs.images) }} + arch: ${{ fromJSON(inputs.archs) }} + network: ["local"] + enable: ["core","rpc","core,rpc,horizon"] + options: [""] + include: ${{ fromJSON(needs.setup.outputs.additional-tests) }} + fail-fast: false + name: 2 test (${{ matrix.image.tag }}, ${{ matrix.arch }}, ${{ matrix.network }}, ${{ matrix.enable }} ${{ matrix.options || '' }}, ${{ matrix.image.tests.continue-on-error && 'continue-on-error' || ''}}) + runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} + continue-on-error: ${{ matrix.image.tests.continue-on-error || false }} + steps: + - name: Free up disk space + if: matrix.network == 'pubnet' + run: | + sudo rm -rf /usr/share/dotnet + sudo rm -rf /usr/local/lib/android + sudo rm -rf /opt/ghc + sudo rm -rf /opt/hostedtoolcache/CodeQL + df -h + - uses: actions/checkout@v2 + with: + repository: ${{ inputs.repo }} + ref: ${{ needs.setup.outputs.sha }} + - name: Download Quickstart Image + uses: actions/download-artifact@v4 + with: + name: image-quickstart-${{ matrix.image.tag }}-${{ matrix.arch }}.tar + path: /tmp/ + - name: Load Quickstart Image + run: docker load -i /tmp/image + - name: Prepare Logs Directory + run: mkdir -p logs + - name: Run Quickstart Image + run: > + docker run + --platform linux/${{ matrix.arch }} + -d + -p + "8000:8000" + -p "11626:11626" + --name stellar + quickstart:${{ matrix.image.tag }}-${{ matrix.arch }} + --${{ matrix.network }} + --enable ${{ matrix.enable }} + ${{ matrix.options }} + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: ^1 + - name: Sleep until supervisor is up + run: sleep 10 + - name: Calculate timeout + id: timeout + run: echo "minutes=$((${{ github.run_attempt }} * 2))" >> $GITHUB_OUTPUT + - name: Run core test + if: ${{ contains(matrix.enable, 'core') }} + timeout-minutes: ${{ fromJSON(steps.timeout.outputs.minutes) }} + run: | + docker logs stellar -f & + echo "supervisorctl tail -f stellar-core" | docker exec -i stellar sh & + go run tests/test_core.go + curl http://localhost:11626/info + - name: Run horizon up test + if: ${{ contains(matrix.enable, 'horizon') }} + timeout-minutes: ${{ fromJSON(steps.timeout.outputs.minutes) }} + run: | + docker logs stellar -f & + echo "supervisorctl tail -f horizon" | docker exec -i stellar sh & + go run tests/test_horizon_up.go + curl http://localhost:8000 + - name: Run horizon core up test + if: ${{ contains(matrix.enable, 'horizon') && matrix.network != 'pubnet' }} + timeout-minutes: ${{ fromJSON(steps.timeout.outputs.minutes) }} + run: | + docker logs stellar -f & + echo "supervisorctl tail -f horizon" | docker exec -i stellar sh & + go run tests/test_horizon_core_up.go + curl http://localhost:8000 + - name: Run horizon ingesting test + if: ${{ contains(matrix.enable, 'horizon') && matrix.network != 'pubnet' }} + timeout-minutes: ${{ fromJSON(steps.timeout.outputs.minutes) }} + run: | + docker logs stellar -f & + echo "supervisorctl tail -f stellar-core" | docker exec -i stellar sh & + echo "supervisorctl tail -f horizon" | docker exec -i stellar sh & + go run tests/test_horizon_ingesting.go + curl http://localhost:8000 + - name: Run friendbot test + if: ${{ contains(matrix.enable, 'horizon') && matrix.network == 'local' }} + timeout-minutes: ${{ fromJSON(steps.timeout.outputs.minutes) }} + run: | + docker logs stellar -f & + echo "supervisorctl tail -f friendbot" | docker exec -i stellar sh & + echo "supervisorctl tail -f horizon" | docker exec -i stellar sh & + go run tests/test_friendbot.go + - name: Run stellar rpc up test + if: ${{ contains(matrix.enable, 'rpc') }} + timeout-minutes: ${{ fromJSON(steps.timeout.outputs.minutes) }} + run: | + docker logs stellar -f & + echo "supervisorctl tail -f stellar-rpc" | docker exec -i stellar sh & + go run tests/test_stellar_rpc_up.go + - name: Run stellar rpc healthy test + if: ${{ contains(matrix.enable, 'rpc') && matrix.network != 'pubnet' }} + timeout-minutes: ${{ fromJSON(steps.timeout.outputs.minutes) }} + run: | + docker logs stellar -f & + echo "supervisorctl tail -f stellar-rpc" | docker exec -i stellar sh & + go run tests/test_stellar_rpc_healthy.go + - name: Prepare Test Logs + if: always() + run: docker cp stellar:/var/log logs + - name: Upload Test Logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: logs-${{ matrix.image.tag }}-${{ matrix.arch }}-test-${{ strategy.job-index }} + path: logs + retention-days: ${{ env.artifact_retention_days_for_logs }}