|
| 1 | +name: "Log in to the ECR pull-through cache (OIDC)" |
| 2 | +description: > |
| 3 | + Assumes the repo's OIDC role, logs Docker in to the ECR pull-through cache and |
| 4 | + exports BASE_REGISTRY so the native JNI build (src/main/jni/build-jni-lib.sh) |
| 5 | + pulls its base images from there instead of public.ecr.aws. Anonymous pulls |
| 6 | + from shared GitHub-hosted runner IPs regularly hit public.ecr.aws's 429 |
| 7 | + "Data limit exceeded". |
| 8 | +
|
| 9 | + Pull requests from forks get neither secrets nor an OIDC token, so role-to-assume |
| 10 | + arrives empty. The action then does nothing, BASE_REGISTRY stays unset, and the |
| 11 | + build falls back to its public.ecr.aws default. The calling job needs |
| 12 | + `permissions: id-token: write`. |
| 13 | +
|
| 14 | + The role's credentials and region are only given to the login step; nothing is |
| 15 | + exported to the job environment, so later steps (make, mvn test, the docker |
| 16 | + builds) never see them. |
| 17 | +
|
| 18 | +inputs: |
| 19 | + role-to-assume: |
| 20 | + description: "ARN of the OIDC role allowed to pull through the cache. Empty skips the login." |
| 21 | + required: false |
| 22 | + default: "" |
| 23 | + aws-region: |
| 24 | + description: "Region of the pull-through cache." |
| 25 | + required: false |
| 26 | + default: "" |
| 27 | + aws-account-id: |
| 28 | + description: "Account that owns the pull-through cache." |
| 29 | + required: false |
| 30 | + default: "" |
| 31 | + |
| 32 | +runs: |
| 33 | + using: composite |
| 34 | + steps: |
| 35 | + - name: Skip ECR login when no role is available |
| 36 | + if: inputs.role-to-assume == '' |
| 37 | + shell: bash |
| 38 | + run: echo "No ECR pull-through role (fork PR or unset secret); base images come from public.ecr.aws." |
| 39 | + |
| 40 | + - name: Assume the ECR pull-through role |
| 41 | + id: creds |
| 42 | + if: inputs.role-to-assume != '' |
| 43 | + continue-on-error: true |
| 44 | + uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4 |
| 45 | + with: |
| 46 | + aws-region: ${{ inputs.aws-region }} |
| 47 | + role-to-assume: ${{ inputs.role-to-assume }} |
| 48 | + role-session-name: GitHubActionsEcrPullThrough |
| 49 | + output-env-credentials: false |
| 50 | + output-credentials: true |
| 51 | + |
| 52 | + # BASE_REGISTRY is only exported once the login succeeds and both JNI base |
| 53 | + # images resolve through the cache (the first pull of a tag needs |
| 54 | + # BatchImportUpstreamImage). On any failure the build keeps the |
| 55 | + # public.ecr.aws default rather than failing on the private registry. |
| 56 | + - name: Log in and export BASE_REGISTRY |
| 57 | + if: inputs.role-to-assume != '' && steps.creds.outcome == 'success' |
| 58 | + shell: bash |
| 59 | + env: |
| 60 | + AWS_ACCESS_KEY_ID: ${{ steps.creds.outputs.aws-access-key-id }} |
| 61 | + AWS_SECRET_ACCESS_KEY: ${{ steps.creds.outputs.aws-secret-access-key }} |
| 62 | + AWS_SESSION_TOKEN: ${{ steps.creds.outputs.aws-session-token }} |
| 63 | + AWS_REGION: ${{ inputs.aws-region }} |
| 64 | + ECR_REGISTRY: ${{ inputs.aws-account-id }}.dkr.ecr.${{ inputs.aws-region }}.amazonaws.com |
| 65 | + run: | |
| 66 | + if ! password=$(aws ecr get-login-password --region "$AWS_REGION"); then |
| 67 | + echo "::warning::ECR login failed; base images come from public.ecr.aws." |
| 68 | + exit 0 |
| 69 | + fi |
| 70 | + echo "::add-mask::$password" |
| 71 | + if ! docker login --username AWS --password-stdin "$ECR_REGISTRY" <<< "$password"; then |
| 72 | + echo "::warning::ECR login failed; base images come from public.ecr.aws." |
| 73 | + exit 0 |
| 74 | + fi |
| 75 | + # Same images as src/main/jni/Dockerfile.glibc and Dockerfile.musl, plus the |
| 76 | + # CodeBuild agent (test/integration/codebuild-local/Dockerfile.agent) and the |
| 77 | + # local-builds image test_one.sh runs it with (tagged per architecture). |
| 78 | + if [ "$(uname -m)" = "aarch64" ]; then local_builds_tag=aarch64; else local_builds_tag=latest; fi |
| 79 | + for image in amazonlinux/amazonlinux:2 docker/library/alpine:3 amazoncorretto/amazoncorretto:8 \ |
| 80 | + "codebuild/local-builds:$local_builds_tag"; do |
| 81 | + if ! docker buildx imagetools inspect "$ECR_REGISTRY/ecr-public/$image" > /dev/null; then |
| 82 | + echo "::warning::$image is not reachable through the ECR pull-through cache; base images come from public.ecr.aws." |
| 83 | + exit 0 |
| 84 | + fi |
| 85 | + done |
| 86 | + # The integration tests run docker inside a CodeBuild local container, which |
| 87 | + # doesn't see this runner's docker login. test_one.sh hands it this |
| 88 | + # file so the container can log in itself. |
| 89 | + password_file="$RUNNER_TEMP/ecr-pull-through-password" |
| 90 | + (umask 077 && printf '%s' "$password" > "$password_file") |
| 91 | + echo "ECR_PASSWORD_FILE=$password_file" >> "$GITHUB_ENV" |
| 92 | + echo "BASE_REGISTRY=$ECR_REGISTRY/ecr-public" >> "$GITHUB_ENV" |
| 93 | +
|
| 94 | + - name: Warn on role assumption failure |
| 95 | + if: inputs.role-to-assume != '' && steps.creds.outcome != 'success' |
| 96 | + shell: bash |
| 97 | + run: echo "::warning::Could not assume the ECR pull-through role; base images come from public.ecr.aws." |
0 commit comments