Feat/redshift auth proxy #4622
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Compatibility Tests | |
| on: | |
| pull_request: | |
| paths: | |
| - 'src/**' | |
| - 'pom.xml' | |
| - 'docker/Dockerfile.native-package' | |
| - 'docker/Dockerfile.compat' | |
| - 'docker/entrypoint.sh' | |
| - 'docker/localstack-parity.sh' | |
| - 'compatibility-tests/**' | |
| - '.github/ci/compat-timing-report.py' | |
| - '.github/workflows/compatibility.yml' | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| compat-aws-cli-shim: | |
| name: compat / aws CLI endpoint resolution | |
| runs-on: ubuntu-24.04-arm | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 | |
| - name: Build compat image | |
| uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 | |
| with: | |
| context: . | |
| file: docker/Dockerfile.compat | |
| build-args: VERSION=latest | |
| load: true | |
| tags: floci-compat-shim-test | |
| # Read-only; warm-compat-caches.yml produces this scope on main. Unlike | |
| # floci-native above, these layers are worth caching: the image builds | |
| # FROM a published floci/floci tag and its cost is a microdnf install | |
| # that changes only when the Dockerfile does. Writing from here would | |
| # put a per-PR copy no other PR can read back into the budget. | |
| cache-from: type=gha,scope=compat-shim | |
| - name: Unflagged aws sqs call routes to AWS_ENDPOINT_URL | |
| run: | | |
| out=$(docker run --rm --entrypoint sh floci-compat-shim-test -c \ | |
| "aws sqs create-queue --queue-name smoke-test 2>&1" || true) | |
| echo "$out" | |
| echo "$out" | grep -q "localhost:4566" \ | |
| || { echo "::error::unflagged aws call did not target localhost:4566"; exit 1; } | |
| echo "$out" | grep -qi "queue.amazonaws.com\|InvalidClientTokenId" \ | |
| && { echo "::error::unflagged aws call reached real AWS endpoint"; exit 1; } | |
| exit 0 | |
| - name: AWS_ENDPOINT_URL_SQS alone routes correctly | |
| run: | | |
| out=$(docker run --rm --entrypoint sh -e AWS_ENDPOINT_URL= \ | |
| -e AWS_ENDPOINT_URL_SQS=http://localhost:4566 \ | |
| floci-compat-shim-test -c \ | |
| "aws sqs create-queue --queue-name smoke-test-service-override 2>&1" || true) | |
| echo "$out" | |
| echo "$out" | grep -q "localhost:4566" \ | |
| || { echo "::error::AWS_ENDPOINT_URL_SQS was not honored"; exit 1; } | |
| echo "$out" | grep -qi "queue.amazonaws.com\|InvalidClientTokenId" \ | |
| && { echo "::error::AWS_ENDPOINT_URL_SQS call reached real AWS endpoint"; exit 1; } | |
| exit 0 | |
| - name: Explicit --endpoint-url before the subcommand overrides AWS_ENDPOINT_URL | |
| run: | | |
| out=$(docker run --rm --entrypoint sh floci-compat-shim-test -c \ | |
| "AWS_ENDPOINT_URL=http://example.com aws --endpoint-url http://other.example.com sqs list-queues 2>&1" || true) | |
| echo "$out" | |
| echo "$out" | grep -q "other.example.com" \ | |
| || { echo "::error::pre-subcommand --endpoint-url flag was not honored over AWS_ENDPOINT_URL"; exit 1; } | |
| - name: Explicit --endpoint-url after the subcommand overrides AWS_ENDPOINT_URL | |
| run: | | |
| out=$(docker run --rm --entrypoint sh floci-compat-shim-test -c \ | |
| "AWS_ENDPOINT_URL=http://example.com aws sqs list-queues --endpoint-url http://other.example.com 2>&1" || true) | |
| echo "$out" | |
| echo "$out" | grep -q "other.example.com" \ | |
| || { echo "::error::post-subcommand --endpoint-url flag was not honored over AWS_ENDPOINT_URL"; exit 1; } | |
| build-native: | |
| name: Build native floci image | |
| runs-on: ubuntu-24.04-arm | |
| timeout-minutes: 30 | |
| steps: | |
| - uses: actions/checkout@v7.0.1 | |
| - uses: graalvm/setup-graalvm@0def53c0fd8534bc13416c9469f5be45265824fd # v1 | |
| with: | |
| java-version: '25' | |
| distribution: 'mandrel' | |
| # no `cache: maven` — it keys on setup-graalvm-Linux-maven-<hash>, which | |
| # only this pull_request-only workflow ever writes. Actions caches are | |
| # ref-scoped, so those writes land in refs/pull/N/merge and no run can | |
| # read another's: it logged "maven cache is not found" on 6 of 6 sampled | |
| # runs while dutifully saving 211 MB each time. Restore ci.yml's cache | |
| # below instead, which push-to-main genuinely populates. | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| # Restore-only, and deliberately keyed identically to ci.yml:54-59 so this | |
| # reads the ~/.m2 that ci.yml's shard 1 saves on every push to main. ci.yml | |
| # stays the single owner of the save; a second writer would just race it. | |
| # Two known partial-hit caveats, both cheap: `runner.os` is Linux for both | |
| # but ci.yml runs x64 while this runs arm64 (Maven artifacts are | |
| # arch-neutral, so only classifier-based natives re-download), and | |
| # `-Dnative` pulls native-image plugins that ci.yml's `mvn test` never | |
| # fetches. Expect most of the ~66s of cold resolution back, not all of it. | |
| - uses: actions/cache/restore@v6.1.0 | |
| with: | |
| path: ~/.m2/repository | |
| key: maven-${{ runner.os }}-${{ hashFiles('pom.xml') }} | |
| restore-keys: maven-${{ runner.os }}- | |
| - name: Build native executable (quick build) | |
| run: mvn clean package -Dnative -DskipTests -B -Dquarkus.native.additional-build-args-append="-Ob" | |
| - name: Stage native binary for packaging | |
| run: | | |
| mkdir -p native/arm64 | |
| cp target/*-runner native/arm64/application | |
| # include any sidecar .so the runtime image may need (matches nightly artifact set) | |
| cp target/*.so native/arm64/ 2>/dev/null || true | |
| - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 | |
| - name: Build native Docker image | |
| uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 | |
| with: | |
| context: . | |
| file: docker/Dockerfile.native-package | |
| tags: floci:test-native | |
| outputs: type=docker,dest=/tmp/floci-native-image.tar | |
| # No layer cache here, deliberately. The `COPY native/$TARGETARCH/` | |
| # below brings in a binary that changes every commit, and Docker layer | |
| # reuse is sequential, so nothing after it can ever be reused. Measured: | |
| # the build imported a cache manifest but reported **zero CACHED | |
| # layers** — it was write-only. `mode=max` still stored the whole image | |
| # including that volatile multi-hundred-MB binary layer, per PR ref, | |
| # which was the largest single consumer of the repo's 10 GB budget. | |
| # The step costs ~19-28s either way. | |
| - name: Compress native image | |
| run: gzip /tmp/floci-native-image.tar | |
| - name: Upload native floci image | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: floci-native-image | |
| path: /tmp/floci-native-image.tar.gz | |
| retention-days: 1 | |
| native-compat-test: | |
| name: native / ${{ matrix.test }} | |
| needs: build-native | |
| runs-on: ubuntu-24.04-arm | |
| timeout-minutes: 20 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| test: | |
| - sdk-test-node | |
| - sdk-test-python | |
| - sdk-test-java | |
| - sdk-test-go | |
| - sdk-test-awscli | |
| - compat-cdk | |
| - compat-terraform | |
| - compat-opentofu | |
| steps: | |
| - name: Download native floci image | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: floci-native-image | |
| path: /tmp | |
| - name: Load native floci image | |
| run: gunzip -c /tmp/floci-native-image.tar.gz | docker load | |
| - name: Create Docker network | |
| run: docker network create compat-net | |
| - name: Start floci | |
| run: | | |
| DOCKER_GID=$(stat -c '%g' /var/run/docker.sock) | |
| docker run -d --name floci --network compat-net \ | |
| -p 4566:4566 \ | |
| -p 7100-7199:7100-7199 \ | |
| -v /var/run/docker.sock:/var/run/docker.sock \ | |
| --group-add "$DOCKER_GID" \ | |
| -e FLOCI_BASE_URL=http://floci:4566 \ | |
| -e FLOCI_SERVICES_DOCKER_NETWORK=compat-net \ | |
| -e FLOCI_HOSTNAME=floci \ | |
| -e FLOCI_SERVICES_IOT_MQTT_ENABLED=true \ | |
| -e FLOCI_SERVICES_LAMBDA_HOT_RELOAD_ENABLED=true \ | |
| -e FLOCI_TLS_ENABLED=true \ | |
| -e FLOCI_SERVICES_EC2_MOCK=true \ | |
| -e FLOCI_SERVICES_REDSHIFT_ENDPOINT_HOST=floci \ | |
| floci:test-native | |
| - name: Wait for floci to be ready | |
| run: timeout 60 bash -c 'until curl -sf http://localhost:4566/ >/dev/null 2>&1; do sleep 1; done' | |
| - name: Checkout repository | |
| uses: actions/checkout@v7.0.1 | |
| with: | |
| sparse-checkout: | | |
| compatibility-tests | |
| .github/ci | |
| - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 | |
| - name: Build test image | |
| uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 | |
| with: | |
| context: compatibility-tests/${{ matrix.test }} | |
| load: true | |
| tags: compat-${{ matrix.test }} | |
| # Read-only on purpose. Actions caches are ref-scoped: a pull_request | |
| # run's writes land in refs/pull/N/merge, private to that PR and | |
| # unreadable by any other. Eight images x every open PR overran the | |
| # repo's 10 GB cache budget (13.2 GB measured, 95% of it in four PR | |
| # refs), so entries were evicted between a PR's own runs and this | |
| # build swung 29s-211s at random. `warm-compat-caches.yml` populates | |
| # these scopes on main instead; PRs read that single shared copy. | |
| cache-from: type=gha,scope=${{ matrix.test }} | |
| - name: Run tests | |
| id: tests | |
| run: | | |
| mkdir -p test-results | |
| FLOCI_IP=$(docker inspect -f '{{(index .NetworkSettings.Networks "compat-net").IPAddress}}' floci) | |
| DOCKER_GID=$(stat -c '%g' /var/run/docker.sock) | |
| EXTRA_ARGS="" | |
| # compat-cdk needs Docker access for CDK's DockerImageFunction (docker build + push to emulated ECR) | |
| if [ "${{ matrix.test }}" = "compat-cdk" ]; then | |
| EXTRA_ARGS="-v /var/run/docker.sock:/var/run/docker.sock --group-add $DOCKER_GID" | |
| fi | |
| # sdk-test-java: mount a host-side directory so the Docker daemon can | |
| # bind-mount hot-reload code paths that are written by the test container. | |
| if [ "${{ matrix.test }}" = "sdk-test-java" ]; then | |
| mkdir -p /tmp/floci-hot-reload | |
| EXTRA_ARGS="$EXTRA_ARGS -v /tmp/floci-hot-reload:/tmp/floci-hot-reload -e HOT_RELOAD_BASE_DIR=/tmp/floci-hot-reload" | |
| fi | |
| # --dns injects Floci's embedded DNS so *.floci wildcard subdomains | |
| # (e.g. my-bucket.floci) resolve to Floci's IP inside the test container. | |
| # FLOCI_S3_VHOST_ENDPOINT tells the S3 virtual-host client to use | |
| # http://floci:4566 as the endpoint base instead of the public DNS fallback. | |
| docker run --rm --network compat-net \ | |
| --dns "${FLOCI_IP}" \ | |
| -e FLOCI_ENDPOINT=http://floci:4566 \ | |
| -e FLOCI_S3_VHOST_ENDPOINT=http://floci:4566 \ | |
| -v "$(pwd)/test-results:/results" \ | |
| $EXTRA_ARGS \ | |
| compat-${{ matrix.test }} | |
| - name: Generate test summary | |
| if: always() && steps.tests.outcome != 'skipped' | |
| uses: test-summary/action@37b508cfee6d4d080eedd00b5bb240a6a784a6a5 # v2 | |
| with: | |
| paths: test-results/*.xml | |
| # The test body inside the container runs its build tool quietly, so the | |
| # job log carries no per-class timings and the slow legs (sdk-test-java, | |
| # ~10 min) are a black box. Surface the timings from the junit XMLs the | |
| # suites already export, and upload the raw XMLs so the numbers are | |
| # machine-readable across runs. | |
| - name: Report slowest test classes | |
| if: always() && steps.tests.outcome != 'skipped' | |
| # Measurement-only: a reporting bug must never fail an otherwise-green leg. | |
| continue-on-error: true | |
| run: python3 .github/ci/compat-timing-report.py test-results | |
| - name: Upload test results | |
| if: always() && steps.tests.outcome != 'skipped' | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: compat-results-${{ matrix.test }} | |
| path: test-results/ | |
| if-no-files-found: warn | |
| - name: Dump floci logs | |
| if: failure() | |
| run: docker logs floci |