diff --git a/.github/actions/build-and-push-ecr-multiarch/README.md b/.github/actions/build-and-push-ecr-multiarch/README.md new file mode 100644 index 0000000..2096598 --- /dev/null +++ b/.github/actions/build-and-push-ecr-multiarch/README.md @@ -0,0 +1,94 @@ +# Build & Push to ECR (Composite Action) + +Builds a Docker image (Linux or Windows) and pushes it to Amazon ECR using OIDC‑assumed AWS credentials. + +## Inputs + +| Name | Required | Default | Description | +|------|----------|---------|-------------| +| `dockerfile` | Yes | — | Path to the Dockerfile. | +| `ecr-repo` | Yes | — | ECR repository name (e.g. `/`). Must already exist. | +| `iam-role` | Yes | — | AWS IAM Role ARN assumable via GitHub OIDC. | +| `context` | No | `.` | Build context directory passed to `docker build`. | +| `image-tag` | No | (auto short SHA) | Explicit image tag; if omitted a short commit SHA is used. | +| `aws-region` | No | `eu-west-1` | AWS region for ECR. | +| `platform` | No | `linux` | `linux` or `windows`. Runner OS must match. | +| `provenance` | No | `false` | Passed to `docker/build-push-action` (Linux only). | + +## Output + +| Name | Description | +|------|-------------| +| `image-uri` | Fully qualified image URI (e.g. `11111111111.dkr.ecr.eu-west-1.amazonaws.com/company/repo:abc1234`). | + +## Usage (Linux – default) + +```yaml +name: Build Linux Image +on: + push: + branches: [ main ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: ./.github/actions/build-and-push-ecr + id: build + with: + dockerfile: + ecr-repo: / + iam-role: # Preferably as ${{ secrets.AWS_OIDC_ROLE_ARN }} + - name: Use image URI + run: echo "Pushed -> ${{ steps.build.outputs.image-uri }}" +``` + +## Usage (Windows image) + +```yaml +name: Build Windows Image +on: workflow_dispatch + +jobs: + build: + runs-on: windows-latest + steps: + - uses: ./.github/actions/build-and-push-ecr + id: build + with: + platform: windows + dockerfile: + ecr-repo: / + iam-role: # Preferably as ${{ secrets.AWS_OIDC_ROLE_ARN }} + - name: Output + shell: powershell + run: echo "Image = ${{ steps.build.outputs.image-uri }}" +``` + +## Notes + +- The caller workflow must choose `runs-on` matching `platform`. +- Windows builds use classic `docker build`; multi-arch (linux+windows) requires separate workflows plus a manifest merge (not included). +- Ensure the ECR repository exists (create separately via IaC or AWS CLI). +- `image-tag` override is optional; omit for automatic short SHA. +- `provenance` only applies to Linux builds (silently ignored on Windows path). + +## Troubleshooting + +| Issue | Cause / Fix | +|-------|-------------| +| Auth failure | Check IAM role trust policy includes GitHub OIDC provider + repo. | +| Repo not found | Create ECR repo or correct `ecr-repo` name. | +| Windows build fails with base image mismatch | Ensure Dockerfile uses a Windows base matching `windows-latest` (e.g. `ltsc2022`). | +| Tag not as expected | Provide `image-tag` input explicitly. | + +## Example: Custom tag + +```yaml +- uses: ./.github/actions/build-and-push-ecr + with: + dockerfile: + ecr-repo: / + iam-role: # Preferably as ${{ secrets.AWS_OIDC_ROLE_ARN }} + image-tag: v1.4.0 +``` \ No newline at end of file diff --git a/.github/actions/build-and-push-ecr-multiarch/action.yml b/.github/actions/build-and-push-ecr-multiarch/action.yml new file mode 100644 index 0000000..1a00c4d --- /dev/null +++ b/.github/actions/build-and-push-ecr-multiarch/action.yml @@ -0,0 +1,93 @@ +name: Build & Push to ECR +description: Build a Docker image (Linux or Windows) and push to AWS ECR +inputs: + dockerfile: + description: Path to Dockerfile + required: true + ecr-repo: + description: ECR repository (e.g. /) + required: true + iam-role: + description: IAM Role ARN to assume via OIDC + required: true + context: + description: Build context path + required: false + default: . + image-tag: + description: Explicit image tag (defaults to short SHA) + required: false + aws-region: + description: AWS region + required: false + default: eu-west-1 + platform: + description: linux or windows + required: false + default: linux + provenance: + description: Enable build provenance (linux only) + required: false + default: "false" +outputs: + image-uri: + description: Fully qualified pushed image URI + value: ${{ steps.image_uri.outputs.image_uri }} +runs: + using: composite + steps: + - name: Compute image tag (Linux) + if: ${{ inputs.platform != 'windows' }} + shell: bash + run: | + if [ -n "${{ inputs.image-tag }}" ]; then + TAG="${{ inputs.image-tag }}" + else + TAG=$(git rev-parse --short "$GITHUB_SHA") + fi + echo "IMAGE_TAG=$TAG" >> "$GITHUB_ENV" + + - name: Compute image tag (Windows) + if: ${{ inputs.platform == 'windows' }} + shell: powershell + run: | + if ("${{ inputs.image-tag }}") { + $tag = "${{ inputs.image-tag }}" + } else { + $tag = (git rev-parse --short $env:GITHUB_SHA) + } + Add-Content -Path $env:GITHUB_ENV -Value "IMAGE_TAG=$tag" + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ inputs.iam-role }} + role-session-name: ecr-build-session + aws-region: ${{ inputs.aws-region }} + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 + + - name: Build & Push (Linux) + if: ${{ inputs.platform != 'windows' }} + uses: docker/build-push-action@v5 + with: + context: ${{ inputs.context }} + file: ${{ inputs.dockerfile }} + push: true + provenance: ${{ inputs.provenance }} + tags: ${{ steps.login-ecr.outputs.registry }}/${{ inputs.ecr-repo }}:${{ env.IMAGE_TAG }} + + - name: Build & Push (Windows) + if: ${{ inputs.platform == 'windows' }} + shell: powershell + run: | + docker build -f "${{ inputs.dockerfile }}" -t ${{ steps.login-ecr.outputs.registry }}/${{ inputs.ecr-repo }}:${{ env.IMAGE_TAG }} "${{ inputs.context }}" + docker push ${{ steps.login-ecr.outputs.registry }}/${{ inputs.ecr-repo }}:${{ env.IMAGE_TAG }} + + - name: Set image URI output + id: image_uri + shell: bash + run: | + echo "image_uri=${{ steps.login-ecr.outputs.registry }}/${{ inputs.ecr-repo }}:${{ env.IMAGE_TAG }}" >> "$GITHUB_OUTPUT"