Browse documentation
This Website
CI/CD Pipeline
The checks and deployment stages that move a change from pull request to ECS.
Overview
The portfolio uses GitHub Actions to automate validation, container publishing and deployment. Separating validation from deployment keeps the development workflow straightforward and allows each responsibility to evolve independently.
The current pipeline consists of two independent workflows:
- Continuous Integration (CI) validates every pull request and change to the main branch.
- Staging Deployment builds, publishes and deploys the application to the staging environment whenever a change is pushed to the main branch.
This approach allows application quality checks and deployment logic to evolve independently while maintaining a repeatable deployment process.
Pipeline Overview
flowchart LR
Feature[Feature Branch]
PR[Pull Request]
CI[CI Workflow]
Merge[Squash Merge]
Deploy[Deploy Staging Workflow]
ECS[Staging Environment]
Feature --> PR
PR --> CI
CI --> Merge
Merge --> Deploy
Deploy --> ECSContinuous Integration
Every pull request triggers the Continuous Integration workflow. The purpose of this workflow is to verify that the application can be successfully built before changes are merged into the main branch.
The CI workflow currently performs the following validation:
| Stage | Purpose |
|---|---|
| ESLint | Checks code quality and consistency. |
| TypeScript | Performs static type checking. |
| Next.js Build | Verifies the application can be compiled for production. |
| Unit and Integration | Runs the Vitest contact-schema and route-handler tests. |
| Browser and Accessibility | Runs the Playwright user-flow, responsive, navigation, theme and axe-core checks. |
| Docker Build and Smoke | Packages the production image, starts it and verifies its HTTP response and non-root runtime user. |
Running these checks on every pull request helps identify issues before they reach the deployment pipeline.
Staging Deployment
Whenever a change is pushed to the main branch, a separate deployment workflow publishes a production container image and deploys it to the staging environment. In the normal development flow this push is produced by squash merging an approved pull request.
The CI and staging deployment workflows are independent. Validation before deployment therefore relies on required pull-request checks and branch protection preventing unvalidated changes from being merged. The deployment workflow responds directly to the resulting push to main rather than waiting for the separate CI run that also executes on that branch.
The deployment workflow performs the following stages:
- Authenticate with AWS using GitHub OIDC.
- Build and publish the Docker image to Amazon ECR.
- Generate a unique image tag using the Git commit SHA and workflow run attempt.
- Retrieve the existing ECS task definition.
- Register a new task definition revision using the newly published image.
- Update the ECS service.
- Wait for the deployment to complete successfully.
- Smoke test the public staging application over HTTPS.
- Generate a deployment summary.
This process creates an immutable deployment artifact for every successful deployment while allowing ECS to perform a rolling update of the running service.
Authentication
GitHub Actions authenticates with AWS using OpenID Connect (OIDC) rather than long-lived access keys.
During deployment, GitHub exchanges its identity token for a short-lived IAM role that is limited to the permissions required for publishing container images and updating the ECS service.
This approach avoids storing permanent AWS credentials within GitHub while following AWS' recommended authentication model for GitHub Actions.
Container Images
Application images are published to Amazon Elastic Container Registry (ECR).
Each deployment produces a uniquely tagged image based on the Git commit SHA and workflow run attempt.
This provides:
- Immutable deployment artifacts.
- Traceability between Git commits and deployed containers.
- The ability to identify exactly which application version is running.
Deployment Strategy
The current deployment strategy targets a dedicated staging environment.
Separating staging from production allows infrastructure changes, deployment workflows and application updates to be validated against a live AWS environment before being promoted to production.
The long-term deployment strategy is to promote the same tested container image through each environment rather than rebuilding environment-specific images.
Future Improvements
The current CI/CD pipeline establishes the foundation for future deployment automation. Planned enhancements include:
- Automated deployment to production following staging validation.
- Replacing the placeholder pre-deployment image-test stage with image-level smoke or end-to-end checks.
- Deployment notifications and release summaries.
- Automated rollback strategies.
- Expanded deployment metrics and observability.