Add C4 Diagrams as Documentation #184
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: PR Commit Stage | |
# This workflow is triggered on pull requests to the main branch | |
on: | |
pull_request: | |
branches: [ main ] | |
jobs: | |
checkout_and_lint: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout Repository | |
uses: actions/checkout@v4 | |
- name: Set up Node.js | |
uses: actions/setup-node@v4 | |
with: | |
node-version: '14.17' | |
- name: Cache Node Modules | |
uses: actions/cache@v4 | |
env: | |
cache-name: cache-node-modules | |
with: | |
# Cache dependencies using a key for installers and dependencies | |
path: node_modules | |
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} | |
restore-keys: | | |
${{ runner.os }}-build-${{ env.cache-name }}- | |
${{ runner.os }}-build- | |
${{ runner.os }}- | |
- name: Install Dependencies | |
run: npm install | |
- name: Run Lint | |
run: npm run lint | |
test: | |
needs: checkout_and_lint | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout Repository | |
uses: actions/checkout@v4 | |
- name: Set up Node.js | |
uses: actions/setup-node@v4 | |
with: | |
node-version: '14.17' | |
- name: Cache Node Modules | |
uses: actions/cache@v4 | |
env: | |
cache-name: cache-node-modules | |
with: | |
# Cache dependencies using a key for installers and dependencies | |
path: node_modules | |
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} | |
restore-keys: | | |
${{ runner.os }}-build-${{ env.cache-name }}- | |
${{ runner.os }}-build- | |
${{ runner.os }}- | |
- name: No-op Test Placeholder | |
run: echo "No tests implemented yet" | |
build-image: | |
needs: [ test ] | |
runs-on: ubuntu-latest | |
outputs: | |
imageURL: ${{ steps.generate_ghcr_tag.outputs.image }} | |
steps: | |
- name: Checkout Repository | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{ github.head_ref }} | |
- name: Set up QEMU | |
uses: docker/setup-qemu-action@v3 | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Log in to GitHub Container Registry | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: generate ghcr tag | |
id: generate_ghcr_tag | |
run: | | |
SHORT_SHA=${{ github.event.pull_request.head.sha }} | |
SHORT_SHA=${SHORT_SHA:0:7} # Using Bash substring extraction | |
echo "image=ghcr.io/${{ github.repository }}/nextjs-app:${{ github.event_name == 'pull_request' && github.head_ref || github.ref_name }}-$SHORT_SHA" >> $GITHUB_OUTPUT | |
- name: Build and Push Docker Image | |
uses: docker/build-push-action@v5 | |
with: | |
build-args: | | |
MAPBOX_API_TOKEN=${{secrets.MAPBOX_API_TOKEN}} | |
platforms: linux/amd64 | |
context: . | |
file: ./Dockerfile | |
push: true | |
tags: | | |
${{ steps.generate_ghcr_tag.outputs.image }} | |
- name: Comment PR with GHCR details | |
uses: peter-evans/create-or-update-comment@v4 | |
with: | |
issue-number: ${{ github.event.pull_request.number }} | |
body: | | |
📦 New Docker Image has been pushed to Github Container Registry (GHCR) | |
Image: ${{ steps.generate_ghcr_tag.outputs.image }} | |
setup-copilot: | |
runs-on: ubuntu-latest | |
outputs: | |
copilot-path: ${{ steps.setup.outputs.copilot-path }} | |
steps: | |
- name: Create a temporary directory for downloading | |
id: setup | |
run: | | |
mkdir -p ${{ runner.temp }}/copilot-download | |
echo "copilot-path=${{ runner.temp }}/copilot-download/copilot" >> $GITHUB_OUTPUT | |
- name: Download Copilot CLI | |
run: | | |
curl -Lo ${{ steps.setup.outputs.copilot-path }} https://github.com/aws/copilot-cli/releases/latest/download/copilot-linux | |
- name: Make binary executable | |
run: chmod +x ${{ steps.setup.outputs.copilot-path }} | |
- name: Upload Copilot CLI to Artifacts | |
uses: actions/upload-artifact@v4 | |
with: | |
name: copilot-cli | |
path: ${{ steps.setup.outputs.copilot-path }} | |
init-copilot: | |
runs-on: ubuntu-latest | |
needs: setup-copilot | |
steps: | |
- name: Download Copilot CLI from Artifacts | |
uses: actions/download-artifact@v4 | |
with: | |
name: copilot-cli | |
path: /usr/local/bin | |
- name: Ensure Copilot is executable | |
run: chmod +x /usr/local/bin/copilot | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: ${{ secrets.AWS_REGION }} | |
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/ocean-watch-deployer | |
role-duration-seconds: 1800 | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{ github.head_ref }} | |
- name: Check for existing Copilot application | |
id: check_app | |
run: | | |
if copilot app ls | grep -qw "ocean-watch"; then | |
echo "App exists." | |
echo "app_exists=true" >> $GITHUB_ENV | |
else | |
echo "App does not exist." | |
echo "app_exists=false" >> $GITHUB_ENV | |
fi | |
- name: Notify User That A Bootstrap is Needed | |
if: env.app_exists == 'false' | |
run: | | |
echo "Manually run the `bootstrap-copilot-project` workflow first." | |
exit 1 | |
shell: bash | |
create-copilot-environment: | |
needs: [ init-copilot ] | |
runs-on: ubuntu-latest | |
steps: | |
- name: Download Copilot CLI from Artifacts | |
uses: actions/download-artifact@v4 | |
with: | |
name: copilot-cli | |
path: /usr/local/bin | |
- name: Ensure Copilot is executable | |
run: chmod +x /usr/local/bin/copilot | |
- name: Configure AWS Credentials | |
id: creds | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: ${{ secrets.AWS_REGION }} | |
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/ocean-watch-deployer | |
role-duration-seconds: 1800 | |
output-credentials: true | |
- name: Checkout Repository | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{ github.head_ref }} | |
- name: Check for existing Copilot environment | |
id: check_environment | |
run: | | |
if copilot env show --name ${{ github.head_ref }} --json; then | |
echo "Environment exists." | |
echo "environment_exists=true" >> $GITHUB_ENV | |
else | |
echo "Environment does not exist." | |
echo "environment_exists=false" >> $GITHUB_ENV | |
fi | |
- name: Initialize Environment | |
id: init-environment | |
if: env.environment_exists == 'false' | |
run: | | |
if ! copilot env init --name ${{ github.head_ref }} --app ocean-watch --default-config --region ${{ secrets.AWS_REGION }} --aws-session-token ${{ steps.creds.outputs.aws-session-token }}; then | |
echo "Failed to initialize environment." | |
exit 1 | |
fi | |
- name: Deploy Environment | |
run: | | |
if ! copilot env deploy --name ${{ github.head_ref }} --app ocean-watch; then | |
echo "Failed to deploy environment." | |
exit 1 | |
fi | |
- name: Commit copilot environment configs | |
run: | | |
git config --global user.email "[email protected]" | |
git config --global user.name "GitHub Action" | |
git add -A # Adds all changes, including untracked files | |
git diff-index --quiet HEAD || git commit -m "AWS copilot environment configs generated by GitHub Actions Bot" | |
git push origin HEAD:${{ github.head_ref }} # Ensure you're pushing to the correct branch | |
deploy: | |
needs: [ build-image, create-copilot-environment ] | |
runs-on: ubuntu-latest | |
steps: | |
- name: Download Copilot CLI from Artifacts | |
uses: actions/download-artifact@v4 | |
with: | |
name: copilot-cli | |
path: /usr/local/bin | |
- name: Ensure Copilot is executable | |
run: chmod +x /usr/local/bin/copilot | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: ${{ secrets.AWS_REGION }} | |
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/ocean-watch-deployer | |
role-duration-seconds: 1800 | |
- name: Checkout Repository | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{ github.head_ref }} | |
- name: Handle AWS Secret --> GHCR Access | |
run: | | |
# Install jq if it's not available | |
sudo apt-get update && sudo apt-get install -y jq | |
SECRET_NAME="ocean-watch-env-${{ github.head_ref }}" | |
SECRET_VALUE='{"username":"${{ secrets.AWS_GHCR_ACCESS_TOKEN }}","password":"${{ secrets.AWS_GHCR_ACCESS_TOKEN }}"}' | |
TAGS='Key=project,Value=OceanWatch Key=program,Value=Oceans Key=application,Value=OceanWatch Key=copilot-application,Value=ocean-watch Key=copilot-environment,Value=${{ github.head_ref }}' | |
DESCRIPTION='Read-only access to github container registry' | |
# Check if the AWS Secret already exists | |
SECRET_INFO=$(aws secretsmanager describe-secret --secret-id $SECRET_NAME || echo "not_found") | |
if [[ "$SECRET_INFO" == "not_found" ]]; then | |
echo "Secret does not exist, creating..." | |
# Create the secret and extract the ARN | |
SECRET_OUTPUT=$(aws secretsmanager create-secret --name $SECRET_NAME --secret-string "$SECRET_VALUE" --tags $TAGS --description "$DESCRIPTION") | |
SECRET_ARN=$(echo $SECRET_OUTPUT | jq -r .ARN) | |
echo "Secret created with ARN: $SECRET_ARN" | |
else | |
echo "Secret already exists." | |
# Extract the ARN from existing secret info | |
SECRET_ARN=$(echo $SECRET_INFO | jq -r .ARN) | |
fi | |
# Store the ARN for use in subsequent steps | |
echo "SECRET_ARN=$SECRET_ARN" >> $GITHUB_ENV | |
- name: Check for existing Copilot service deployment | |
id: check_service_deployment | |
run: | | |
if copilot svc show --name nextjs-app --json; then | |
echo "Service exists." | |
echo "service_exists=true" >> $GITHUB_ENV | |
else | |
echo "Service does not exist." | |
echo "service_exists=false" >> $GITHUB_ENV | |
fi | |
- name: Initialize Service | |
id: init-service | |
if: env.service_exists == 'false' | |
run: | | |
export IMAGE_LOCATION="${{ needs.build-image.outputs.imageURL }}" | |
export GHCR_ACCESS="${{ env.SECRET_ARN }}" | |
if ! copilot svc init --app ocean-watch --name nextjs-app --svc-type "Load Balanced Web Service"; then | |
echo "Failed to initialize service." | |
exit 1 | |
fi | |
- name: Deploy App to AWS using Copilot | |
run: | | |
export IMAGE_LOCATION="${{ needs.build-image.outputs.imageURL }}" | |
export GHCR_ACCESS="${{ env.SECRET_ARN }}" | |
if ! copilot svc deploy --force --name nextjs-app --env ${{ github.head_ref }}; then | |
echo "Failed to deploy service." | |
copilot svc delete --name nextjs-app --env ${{ github.head_ref }} --yes | |
exit 1 | |
fi | |
- name: Show Service Information | |
id: service_info | |
run: | | |
ENV_NAME="${{ github.head_ref }}" | |
SERVICE_JSON=$(copilot svc show --app ocean-watch --name nextjs-app --json) | |
SERVICE_URL=$(echo "$SERVICE_JSON" | jq -r --arg ENV_NAME "$ENV_NAME" '.routes[] | select(.environment == $ENV_NAME) | .url') | |
if [[ -z "$SERVICE_URL" || "$SERVICE_URL" == "null" ]]; then | |
echo "No URL found for the specified environment: $ENV_NAME" | |
echo "$SERVICE_JSON" | |
exit 1 | |
fi | |
echo "url=$SERVICE_URL" >> $GITHUB_OUTPUT | |
echo "Service URL: $SERVICE_URL" | |
- name: Comment PR with Service URL | |
if: github.event_name == 'pull_request' | |
uses: peter-evans/create-or-update-comment@v4 | |
with: | |
issue-number: ${{ github.event.pull_request.number }} | |
body: | | |
🚀 Deployment successful! | |
🌐 Your service in environment `${{ github.head_ref }}` is now available at: ${{ steps.service_info.outputs.url }} | |
- name: Commit Copilot Service Configs | |
id: commit-changes | |
run: | | |
# Capture the original SHA for comparison | |
ORIG_SHA="${{ github.event.pull_request.head.sha }}" | |
git config --global user.email "[email protected]" | |
git config --global user.name "GitHub Action" | |
git add -A # Adds all changes, including untracked files | |
git diff-index --quiet HEAD || git commit -m "AWS copilot configs generated by GitHub Actions Bot" | |
git push origin HEAD:${{ github.head_ref }} # Ensure you're pushing to the correct branch | |
# Capture the current SHA after potential commit | |
CURRENT_SHA=$(git rev-parse HEAD) | |
# Compare SHAs to determine if a new commit was made | |
if [ "$ORIG_SHA" != "$CURRENT_SHA" ]; then | |
echo "AWS Copilot Configuration Changes Detected." | |
echo "config_changes_exist=true" >> $GITHUB_ENV | |
else | |
echo "No AWS Copilot Configuration Changes Detected." | |
echo "config_changes_exist=false" >> $GITHUB_ENV | |
fi | |
shell: bash | |
- name: Log in to GitHub Container Registry | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Add Updated SHA to GHCR Image | |
if: env.config_changes_exist == 'true' | |
run: | | |
ORIG_SHORT_SHA=${{ github.event.pull_request.head.sha }} | |
ORIG_SHORT_SHA=${ORIG_SHORT_SHA:0:7} # Using Bash substring extraction | |
CURRENT_SHORT_SHA=$(git rev-parse HEAD) | |
CURRENT_SHORT_SHA=${CURRENT_SHORT_SHA:0:7} # Using Bash substring extraction | |
docker pull ghcr.io/${{ github.repository }}/nextjs-app:${{ github.event.pull_request.head.ref }}-$ORIG_SHORT_SHA | |
docker tag ghcr.io/${{ github.repository }}/nextjs-app:${{ github.event.pull_request.head.ref }}-$ORIG_SHORT_SHA ghcr.io/${{ github.repository }}/nextjs-app:${{ github.event.pull_request.head.ref }}-$CURRENT_SHORT_SHA | |
docker push --all-tags ghcr.io/${{ github.repository }}/nextjs-app | |
shell: bash |