Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ECS task for RedwoodJS console #38

Merged
merged 15 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
# Require admin approval when Postgres root CA bundle is modified
/api/db/rds-combined-ca-bundle.pem @usdigitalresponse/grants-admins

# Require admin approval when GPG keys are modified
aws-public-key.gpg @usdigitalresponse/grants-admins

# Require admin approval for special doc modifications
README.md @usdigitalresponse/grants-admins
LICENSE @usdigitalresponse/grants-admins
Expand Down
207 changes: 178 additions & 29 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,58 +18,66 @@ on:
description: Whether to build zip artifacts for API functions.
type: boolean
default: true
build-console-image:
description: Whether to build a RedwoodJS console Docker image.
type: boolean
default: true
build-web:
description: Whether to build website distribution artifacts for the client package.
type: boolean
default: true
api-image-args-ref:
api-image-name:
description: Name of the docker image. Use caution when setting a non-default value.
type: string
default: ${{ github.repository }}-api
api-function-artifact-retention-days:
description: Number of days to retain API function build artifacts.
type: number
default: 90
console-image-name:
description: Name of the docker image. Use caution when setting a non-default value.
type: string
default: ${{ github.repository }}-console
docker-image-args-ref:
description: Ref name for the build commit, like refs/heads/my-feature-branch-1.
type: string
required: true
api-image-artifacts-retention-days:
docker-image-artifacts-retention-days:
description: Number of days to store Docker attestation artifacts.
type: number
default: 90
api-image-upload-attestations:
description: Whether to upload attestation files for the Docker build as artifacts.
docker-image-upload-attestations:
description: Whether to upload attestation files for Docker builds as artifacts.
type: boolean
default: false
api-image-push:
docker-image-push:
description: Whether to push Docker images to the registry after building.
type: boolean
default: true
api-image-name:
description: Name of the docker image. Use caution when setting a non-default value.
type: string
default: ${{ github.repository }}-api
api-image-registry:
docker-image-registry:
description: The Docker image registry. Use caution when setting a non-default value.
type: string
default: ghcr.io
api-image-tag-latest:
docker-image-tag-latest:
description: Tags image builds with `latest`.
type: boolean
default: false
api-image-tag-production:
docker-image-tag-production:
description: Tags image builds with `production`.
type: boolean
required: false
api-image-tag-pr:
docker-image-tag-pr:
description: A PR number to add as a Docker image tag (as `pr-<value>`) when building for a pull request.
type: string
required: false
api-image-tag-release:
docker-image-tag-release:
description: A tag value that, if provided, signifies the release version associated with the Docker image.
type: string
required: false
api-image-version:
docker-image-version:
description: Value to set for the `org.opencontainers.image.version label`.
type: string
default: ""
api-function-artifact-retention-days:
description: Number of days to retain API function build artifacts.
type: number
default: 90
web-artifact-retention-days:
description: Number of days to retain website build artifacts.
type: number
Expand All @@ -83,6 +91,8 @@ on:
value: ${{ jobs.api-docker-image.result }}
build-api-functions-result:
value: ${{ jobs.api-function-zips.result }}
build-console-image-result:
value: ${{ jobs.redwood-console-image.result }}
build-web-result:
value: ${{ jobs.web-bundle.result }}
api-image-digest:
Expand All @@ -97,6 +107,12 @@ on:
value: ${{ jobs.api-function-zips.outputs.artifacts-path }}
api-functions-checksums-sha256:
value: ${{ jobs.api-function-zips.outputs.checksums-sha256 }}
console-image-digest:
value: ${{ jobs.redwood-console-image.outputs.digest }}
console-attestation-artifacts-key:
value: ${{ jobs.redwood-console-image.outputs.attestation-artifacts-key }}
console-attestation-artifacts-path:
value: ${{ jobs.redwood-console-image.outputs.attestation-artifacts-path }}
web-artifacts-key:
value: ${{ jobs.web-bundle.outputs.artifacts-key }}
web-artifacts-path:
Expand Down Expand Up @@ -151,15 +167,15 @@ jobs:
id: meta
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
with:
images: ${{ inputs.api-image-registry }}/${{ inputs.api-image-name }}
images: ${{ inputs.docker-image-registry }}/${{ inputs.api-image-name }}
tags: |
type=raw,enable=true,priority=100,prefix=sha-,value=${{ steps.commit-sha.outputs.long }}
type=raw,enable=${{ inputs.api-image-tag-release != '' }},priority=200,value=${{ inputs.api-image-tag-release }}
type=raw,enable=${{ inputs.api-image-tag-latest }},priority=300,value=latest
type=raw,enable=${{ inputs.api-image-tag-pr != '' }},priority=600,prefix=pr-,value=${{ inputs.api-image-tag-pr }}
type=raw,enable=${{ inputs.docker-image-tag-release != '' }},priority=200,value=${{ inputs.docker-image-tag-release }}
type=raw,enable=${{ inputs.docker-image-tag-latest }},priority=300,value=latest
type=raw,enable=${{ inputs.docker-image-tag-pr != '' }},priority=600,prefix=pr-,value=${{ inputs.docker-image-tag-pr }}
labels: |
org.opencontainers.image.title=${{ inputs.api-image-name }}
org.opencontainers.image.version=${{ inputs.api-image-version }}
org.opencontainers.image.version=${{ inputs.docker-image-version }}
org.opencontainers.image.revision=${{ steps.commit-sha.outputs.long }}
com.datadoghq.tags.service=cpf-reporter
com.datadoghq.tags.version=${{ steps.commit-sha.outputs.long }}
Expand All @@ -178,19 +194,152 @@ jobs:
with:
context: .
github-token: ${{ secrets.GITHUB_TOKEN }}
push: ${{ inputs.api-image-push }}
push: ${{ inputs.docker-image-push }}
file: Dockerfile
target: api_serve
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
pull: true
provenance: true
sbom: true
build-args: |
GIT_COMMIT=${{ inputs.ref }}
GIT_REF=${{ inputs.docker-image-args-ref }}
TIMESTAMP=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }}
- name: Publish build results
run: |
REPORT_FILE=$(mktemp -t summary.md.XXXXX)
cat >> $REPORT_FILE << 'ENDOFREPORT'
## Docker Build Summary

**Image ID:** `${{ steps.build-push.outputs.imageid }}`
**Image Digest:** `${{ steps.build-push.outputs.digest }}`

<details>
<summary>Bake File</summary>

```json
${{ steps.bakefile.outputs.result }}
```

</details>
<details>
<summary>Build Metadata</summary>

```json
${{ steps.build-push.outputs.metadata }}
```

</details>
ENDOFREPORT
cat "$REPORT_FILE" >> $GITHUB_STEP_SUMMARY
- name: Store attestations
id: store-attestations
if: inputs.docker-image-upload-attestations
run: |
ATTESTATIONS_DIR=$(mktemp -d)
echo "path=$ATTESTATIONS_DIR" >> $GITHUB_OUTPUT
docker buildx imagetools inspect "$INSPECT_NAME" --format "{{ json .SBOM }}" > $ATTESTATIONS_DIR/sbom.sdpx.json
docker buildx imagetools inspect "$INSPECT_NAME" --format "{{ json .Provenance }}" > $ATTESTATIONS_DIR/provenance.json
env:
INSPECT_NAME: ${{ inputs.docker-image-registry }}/${{ inputs.api-image-name }}@${{ steps.build-push.outputs.digest }}
- name: Upload attestations
if: steps.store-attestations.outcome == 'success'
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
with:
name: ${{ env.ATTESTATION_ARTIFACTS_KEY }}
path: ${{ steps.store-attestations.outputs.path }}
if-no-files-found: error
retention-days: ${{ inputs.docker-image-artifacts-retention-days }}

redwood-console-image:
name: Build RedwoodJS console Docker image
if: inputs.build-console-image
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
env:
ATTESTATION_ARTIFACTS_KEY: "console-image-attestations-${{ inputs.ref }}"
outputs:
commit-tag: ${{ inputs.ref }}
digest: ${{ steps.build-push.outputs.digest }}
attestation-artifacts-key: ${{ env.ATTESTATION_ARTIFACTS_KEY }}
attestation-artifacts-path: ${{ steps.store-attestations.outputs.path }}
steps:
- uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0
with:
disable-sudo: true
egress-policy: audit
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
id: checkout
with:
ref: ${{ inputs.ref }}
show-progress: 'false'
persist-credentials: 'false'
- name: Set build info for the checked-out commit
id: commit-sha
run: echo "long=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
- name: Set up QEMU
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0
with:
platforms: linux/amd64,linux/arm64
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
with:
platforms: linux/amd64,linux/arm64
- name: Authenticate docker
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
with:
images: ${{ inputs.docker-image-registry }}/${{ inputs.console-image-name }}
tags: |
type=raw,enable=true,priority=100,prefix=sha-,value=${{ steps.commit-sha.outputs.long }}
type=raw,enable=${{ inputs.docker-image-tag-release != '' }},priority=200,value=${{ inputs.docker-image-tag-release }}
type=raw,enable=${{ inputs.docker-image-tag-latest }},priority=300,value=latest
type=raw,enable=${{ inputs.docker-image-tag-pr != '' }},priority=600,prefix=pr-,value=${{ inputs.docker-image-tag-pr }}
labels: |
org.opencontainers.image.title=${{ inputs.console-image-name }}
org.opencontainers.image.version=${{ inputs.docker-image-version }}
org.opencontainers.image.revision=${{ steps.commit-sha.outputs.long }}
- name: Set bake file definition as step output
id: bakefile
run: |
BAKEFILE_CONTENTS="$(cat $BAKEFILE_PATH)"
echo "result<<ENDOFBAKEFILE" >> $GITHUB_OUTPUT
echo "$BAKEFILE_CONTENTS" >> $GITHUB_OUTPUT
echo "ENDOFBAKEFILE" >> $GITHUB_OUTPUT
env:
BAKEFILE_PATH: ${{ steps.meta.outputs.bake-file }}
- name: Build and push Docker image
id: build-push
uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0
with:
context: .
github-token: ${{ secrets.GITHUB_TOKEN }}
push: ${{ inputs.docker-image-push }}
file: Dockerfile
target: console
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
pull: true
provenance: true
sbom: true
build-args: |
GIT_COMMIT=${{ inputs.ref }}
GIT_REF=${{ inputs.api-image-args-ref }}
GIT_REF=${{ inputs.docker-image-args-ref }}
TIMESTAMP=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }}
- name: Publish build results
run: |
Expand Down Expand Up @@ -221,22 +370,22 @@ jobs:
cat "$REPORT_FILE" >> $GITHUB_STEP_SUMMARY
- name: Store attestations
id: store-attestations
if: inputs.api-image-upload-attestations
if: inputs.docker-image-upload-attestations
run: |
ATTESTATIONS_DIR=$(mktemp -d)
echo "path=$ATTESTATIONS_DIR" >> $GITHUB_OUTPUT
docker buildx imagetools inspect "$INSPECT_NAME" --format "{{ json .SBOM }}" > $ATTESTATIONS_DIR/sbom.sdpx.json
docker buildx imagetools inspect "$INSPECT_NAME" --format "{{ json .Provenance }}" > $ATTESTATIONS_DIR/provenance.json
env:
INSPECT_NAME: ${{ inputs.api-image-registry }}/${{ inputs.api-image-name }}@${{ steps.build-push.outputs.digest }}
INSPECT_NAME: ${{ inputs.docker-image-registry }}/${{ inputs.console-image-name }}@${{ steps.build-push.outputs.digest }}
- name: Upload attestations
if: steps.store-attestations.outcome == 'success'
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
with:
name: ${{ env.ATTESTATION_ARTIFACTS_KEY }}
path: ${{ steps.store-attestations.outputs.path }}
if-no-files-found: error
retention-days: ${{ inputs.api-image-artifacts-retention-days }}
retention-days: ${{ inputs.docker-image-artifacts-retention-days }}

api-function-zips:
name: Build API Lambda function zip artifacts
Expand Down
19 changes: 10 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,15 @@ jobs:
uses: ./.github/workflows/build.yml
with:
ref: ${{ github.event.pull_request.head.sha }}
docker-image-push: true
docker-image-args-ref: ${{ github.ref }}
docker-image-tag-latest: false
docker-image-tag-pr: "${{ github.event.pull_request.number }}"
docker-image-upload-attestations: true
docker-image-artifacts-retention-days: 14
docker-image-version: "rc-pr-${{ github.event.pull_request.number }}"
build-api-image: true
api-image-push: true
api-image-args-ref: ${{ github.ref }}
api-image-tag-latest: false
api-image-tag-pr: "${{ github.event.pull_request.number }}"
api-image-version: "rc-pr-${{ github.event.pull_request.number }}"
api-image-upload-attestations: true
api-image-artifacts-retention-days: 14
build-console-image: true
build-api-functions: true
api-function-artifact-retention-days: 14
build-web: true
Expand Down Expand Up @@ -83,8 +84,8 @@ jobs:
concurrency-group: run_terraform-staging
api-functions-artifacts-key: ${{ needs.build.outputs.api-functions-artifacts-key }}
api-functions-artifacts-path: ${{ needs.build.outputs.api-functions-artifacts-path }}
api-image-tag: ${{ github.event.pull_request.head.sha }}
api-image-digest: ${{ needs.build.outputs.api-image-digest }}
console-image-tag: ${{ github.event.pull_request.head.sha }}
console-image-digest: ${{ needs.build.outputs.console-image-digest }}
web-artifacts-key: ${{ needs.build.outputs.web-artifacts-key }}
web-artifacts-path: ${{ needs.build.outputs.web-artifacts-path }}
aws-region: us-west-2
Expand Down
17 changes: 9 additions & 8 deletions .github/workflows/deploy-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,14 @@ jobs:
uses: ./.github/workflows/build.yml
with:
ref: ${{ github.sha }}
docker-image-push: true
docker-image-args-ref: ${{ github.ref }}
docker-image-tag-latest: true
docker-image-upload-attestations: true
docker-image-artifacts-retention-days: 14
docker-image-version: "rc-${{ github.sha }}"
build-api-image: true
api-image-push: true
api-image-args-ref: ${{ github.ref }}
api-image-tag-latest: true
api-image-version: "rc-${{ github.sha }}"
api-image-upload-attestations: true
api-image-artifacts-retention-days: 14
build-console-image: true
build-api-functions: true
api-function-artifact-retention-days: 14
build-web: true
Expand Down Expand Up @@ -79,8 +80,8 @@ jobs:
concurrency-group: run_terraform-staging
api-functions-artifacts-key: ${{ needs.build.outputs.api-functions-artifacts-key }}
api-functions-artifacts-path: ${{ needs.build.outputs.api-functions-artifacts-path }}
api-image-tag: ${{ github.sha }}
api-image-digest: ${{ needs.build.outputs.api-image-digest }}
console-image-tag: ${{ github.sha }}
console-image-digest: ${{ needs.build.outputs.console-image-digest }}
web-artifacts-key: ${{ needs.build.outputs.web-artifacts-key }}
web-artifacts-path: ${{ needs.build.outputs.web-artifacts-path }}
aws-region: us-west-2
Expand Down
Loading
Loading