Skip to content
Draft
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
118 changes: 72 additions & 46 deletions .github/workflows/deploy-catalog.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Deploy catalog to ECR
name: "Catalog: build & push"

on:
push:
Expand All @@ -8,61 +8,87 @@ on:
- '.github/workflows/deploy-catalog.yaml'
- 'catalog/**'
- 'shared/**'
pull_request:
paths:
- '.github/workflows/deploy-catalog.yaml'
- 'catalog/**'
- 'shared/**'

jobs:
deploy-catalog-ecr:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: catalog
# These permissions are needed to interact with GitHub's OIDC Token endpoint.
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
- uses: docker/setup-buildx-action@v4
- name: Build image
uses: docker/build-push-action@v7
with:
context: .
file: catalog/Dockerfile
tags: catalog:${{ github.sha }}
push: false
# On master, export a tarball for the push jobs below; on pull
# requests the build itself is the check and nothing consumes it.
outputs: ${{ github.event_name == 'push' && 'type=docker,dest=/tmp/catalog-image.tar' || '' }}
# One cache scope for both events: master builds warm the cache PRs
# read (the reverse is impossible — PR caches are isolated).
# ignore-error: fork PRs can't write the cache; worst case anywhere
# is a colder next build.
cache-from: type=gha,scope=catalog
cache-to: type=gha,mode=max,scope=catalog,ignore-error=true
- uses: actions/upload-artifact@v7
if: github.event_name == 'push'
with:
node-version-file: 'catalog/package.json'
cache: 'npm'
cache-dependency-path: 'catalog/package-lock.json'
- run: npm ci
- run: npm run build
- name: Configure AWS credentials from Prod account
uses: aws-actions/configure-aws-credentials@v6
name: catalog-image
path: /tmp/catalog-image.tar
retention-days: 1

push:
if: github.event_name == 'push'
needs: build
runs-on: ubuntu-latest
# These permissions are needed to interact with GitHub's OIDC Token endpoint.
permissions:
id-token: write
strategy:
# Targets are independent, so a failed one is retried alone via "Re-run
# failed jobs" — necessary for mp, which can't be re-pushed under the
# same tag, so any re-run replaying its successful push would fail.
fail-fast: false
matrix:
include:
- target: prod
role: arn:aws:iam::730278974607:role/github/GitHub-Quilt
region: us-east-1
repository: quiltdata/catalog
- target: mp
role: arn:aws:iam::730278974607:role/github/GitHub-Quilt
region: us-east-1
registry_id: "709825985650"
repository: quilt-data/quilt-payg-catalog
- target: govcloud
role: arn:aws-us-gov:iam::313325871032:role/github/GitHub-Quilt
region: us-gov-east-1
repository: quiltdata/catalog
steps:
- uses: actions/download-artifact@v8
with:
role-to-assume: arn:aws:iam::730278974607:role/github/GitHub-Quilt
aws-region: us-east-1
- name: Login to Prod ECR
id: login-prod-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Login to MP ECR
id: login-mp-ecr
uses: aws-actions/amazon-ecr-login@v2
name: catalog-image
path: /tmp
- run: docker load -i /tmp/catalog-image.tar
- uses: aws-actions/configure-aws-credentials@v6
with:
registries: 709825985650
- name: Configure AWS credentials from GovCloud account
uses: aws-actions/configure-aws-credentials@v6
role-to-assume: ${{ matrix.role }}
aws-region: ${{ matrix.region }}
- uses: aws-actions/amazon-ecr-login@v2
id: ecr
with:
role-to-assume: arn:aws-us-gov:iam::313325871032:role/github/GitHub-Quilt
aws-region: us-gov-east-1
- name: Login to GovCloud ECR
id: login-govcloud-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build and push Docker image to Prod, MP and GovCloud ECR
registries: ${{ matrix.registry_id }}
- name: Tag and push
env:
ECR_REGISTRY_PROD: ${{ steps.login-prod-ecr.outputs.registry }}
ECR_REGISTRY_GOVCLOUD: ${{ steps.login-govcloud-ecr.outputs.registry }}
ECR_REGISTRY_MP: ${{ steps.login-mp-ecr.outputs.registry }}
ECR_REPOSITORY: quiltdata/catalog
ECR_REPOSITORY_MP: quilt-data/quilt-payg-catalog
IMAGE_TAG: ${{ github.sha }}
IMAGE: ${{ steps.ecr.outputs.registry }}/${{ matrix.repository }}:${{ github.sha }}
run: |
docker buildx build \
-t $ECR_REGISTRY_PROD/$ECR_REPOSITORY:$IMAGE_TAG \
-t $ECR_REGISTRY_GOVCLOUD/$ECR_REPOSITORY:$IMAGE_TAG \
-t $ECR_REGISTRY_MP/$ECR_REPOSITORY_MP:$IMAGE_TAG \
.
docker push $ECR_REGISTRY_PROD/$ECR_REPOSITORY:$IMAGE_TAG
docker push $ECR_REGISTRY_GOVCLOUD/$ECR_REPOSITORY:$IMAGE_TAG
docker push $ECR_REGISTRY_MP/$ECR_REPOSITORY_MP:$IMAGE_TAG
docker tag catalog:${{ github.sha }} "$IMAGE"
docker push "$IMAGE"
1 change: 0 additions & 1 deletion catalog/.dockerignore

This file was deleted.

23 changes: 18 additions & 5 deletions catalog/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Build context is the repo root, not catalog/ — the webpack build resolves
# modules from ../shared (see internals/webpack/webpack.base.js).
FROM node:26-trixie-slim@sha256:715e55e4b84e4bb0ff48e49b398a848f08e55daed8eb6a0ea1839ae53bc57583 AS build

WORKDIR /src/catalog

# Manifests only, so editing app sources doesn't invalidate `npm ci`.
COPY catalog/package.json catalog/package-lock.json ./
RUN --mount=type=cache,target=/root/.npm npm ci

COPY shared /src/shared
COPY catalog ./
RUN npm run build

FROM amazonlinux:2023.11.20260406.2
MAINTAINER Quilt Data, Inc. support@quilt.bio

Check warning on line 16 in catalog/Dockerfile

View workflow job for this annotation

GitHub Actions / build

The MAINTAINER instruction is deprecated, use a label instead to define an image author

MaintainerDeprecated: Maintainer instruction is deprecated in favor of using label More info: https://docs.docker.com/go/dockerfile/rule/maintainer-deprecated/

ENV LC_ALL=C.UTF-8
ENV LANG=C.UTF-8
Expand All @@ -13,16 +27,15 @@
ln -sf /dev/stderr /var/log/nginx/error.log

# Set up nginx
COPY nginx.conf /etc/nginx/nginx.conf
COPY nginx-web.conf /etc/nginx/conf.d/default.conf
COPY catalog/nginx.conf /etc/nginx/nginx.conf
COPY catalog/nginx-web.conf /etc/nginx/conf.d/default.conf

ARG NGINX_STATIC_DIR=/usr/share/nginx/html
# Copy pre-built catalog assets to nginx
RUN rm -rf $NGINX_STATIC_DIR
COPY build $NGINX_STATIC_DIR
COPY --from=build /src/catalog/build $NGINX_STATIC_DIR

# Copy config file
COPY config.json.tmpl config.json.tmpl
COPY catalog/config.json.tmpl config.json.tmpl

RUN ln -s /tmp/config.json $NGINX_STATIC_DIR/config.json && \
ln -s /tmp/config.js $NGINX_STATIC_DIR/config.js
Expand All @@ -32,6 +45,6 @@

# Substitute environment variables into config.json and generate config.js based on that before starting nginx.
# Note: use "exec" because otherwise the shell will catch Ctrl-C and other signals.
CMD envsubst < config.json.tmpl > /tmp/config.json \

Check warning on line 48 in catalog/Dockerfile

View workflow job for this annotation

GitHub Actions / build

JSON arguments recommended for ENTRYPOINT/CMD to prevent unintended behavior related to OS signals

JSONArgsRecommended: JSON arguments recommended for CMD to prevent unintended behavior related to OS signals More info: https://docs.docker.com/go/dockerfile/rule/json-args-recommended/
&& echo "window.QUILT_CATALOG_CONFIG = `cat /tmp/config.json`" > /tmp/config.js \
&& exec nginx -g 'daemon off;'
17 changes: 17 additions & 0 deletions catalog/Dockerfile.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Scoped to catalog/Dockerfile (BuildKit reads <dockerfile>.dockerignore), so
# other images' build contexts are unaffected.
#
# The context is the repo root, but the build only needs catalog/ and shared/.
# Allow-list rather than deny-list: a new top-level directory stays out by
# default instead of silently bloating the context.
*
!catalog
!shared

# Local artifacts that would otherwise leak in from a dirty working tree.
# catalog/build especially: a stale one must not shadow the in-image build.
catalog/node_modules
catalog/build
catalog/coverage
catalog/stats.json
**/.DS_Store