# CI/CD for the public Nosterm client. # # - On every push/PR: install, lint, type-check, test, and build the SPA. # - On push to main / a v* tag: additionally build the container image and # push it to ECR Public (anonymous pulls) so anyone can `docker pull` it. # # This is the PUBLIC contribution repo — it builds and ships ONLY the client # image to the public registry. It deliberately does not touch private ECR or # redeploy any environment; promoting an image to a live site is handled out of # band by the private ops pipeline. # # Targets Gitea 1.21 Actions on a self-hosted (EC2) runner. AWS auth uses the # runner's ambient IAM role (no stored credentials): `aws ecr-public # get-login-password` mints a short-lived token for `docker login`. The runner # role needs ECR Public push permissions (ecr-public:GetAuthorizationToken, # sts:GetServiceBearerToken, BatchCheckLayerAvailability, Put*/Upload*/Complete*). name: ci env: # ECR Public is always authenticated via the us-east-1 endpoint, regardless # of where images are served from. AWS_REGION: us-east-1 # public mirror for anonymous `docker pull`. k3k1z1x5 is the account's ECR # Public registry alias; the repo name (nosterm) is provisioned out of band. ECR_PUBLIC_REGISTRY: public.ecr.aws/k3k1z1x5 ECR_PUBLIC_REPO: nosterm on: push: branches: [main] tags: ['v*'] pull_request: jobs: build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Node uses: actions/setup-node@v4 with: node-version: 20 cache: npm - name: Install dependencies run: npm ci - name: Lint (prettier + eslint) run: npm run lint - name: Type-check (svelte-check) run: npm run check - name: Unit tests (vitest) run: npm test - name: Build (static SPA) run: npm run build image: needs: build # Publish only from the default branch and version tags, never from PRs. if: gitea.event_name == 'push' && (gitea.ref == 'refs/heads/main' || startsWith(gitea.ref, 'refs/tags/v')) runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Install AWS CLI # runner image ships without aws; install v2 if it's missing. run: | if ! command -v aws >/dev/null 2>&1; then apt-get update -qq apt-get install -y -qq curl unzip curl -fsSL "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o /tmp/awscliv2.zip unzip -q /tmp/awscliv2.zip -d /tmp /tmp/aws/install fi aws --version - name: Log in to Amazon ECR Public # ECR Public auth is a separate endpoint (always us-east-1) and its own # login user (AWS). This is push auth; anonymous pulls need no login. run: | aws ecr-public get-login-password --region us-east-1 \ | docker login --username AWS --password-stdin public.ecr.aws - name: Build and push image shell: bash run: | set -eo pipefail IMAGE="$ECR_PUBLIC_REGISTRY/$ECR_PUBLIC_REPO" # tag by commit sha for traceability. docker build -t "$IMAGE:${{ gitea.sha }}" . docker push "$IMAGE:${{ gitea.sha }}" # move :latest only on main. if [ "${{ gitea.ref }}" = "refs/heads/main" ]; then docker tag "$IMAGE:${{ gitea.sha }}" "$IMAGE:latest" docker push "$IMAGE:latest" fi # on a v* tag, also push that version tag. case "${{ gitea.ref }}" in refs/tags/v*) VERSION="${{ gitea.ref_name }}" docker tag "$IMAGE:${{ gitea.sha }}" "$IMAGE:$VERSION" docker push "$IMAGE:$VERSION" ;; esac