Files
portfolio/.github/workflows/main.yml
Denshooter 180b9aa9f8 full upgrade (#31)
*  chore: update CI workflow to include testing and multi-arch build (#29)

*  chore: remove unused dependencies from package-lock.json and updated to a better local dev environment (#30)

*  test: add unit tests

*  test: add unit tests for whole project

*  feat: add whatwg-fetch for improved fetch support

*  chore: update Node.js version to 22 in workflow

*  refactor: update types and improve email handling tests

*  refactor: remove unused imports

*  fix: normalize image name to lowercase in workflows

*  fix: ensure Docker image names are consistently lowercase

*  chore: update

*  chore: update base URL to use secret variable

*  chore: update to login to ghcr

*  fix: add missing 'fi' to close if statement in workflow
2025-02-16 16:36:21 +01:00

119 lines
4.2 KiB
YAML

name: CI and Deploy to Raspberry Pi
on:
push:
branches:
- production
- dev
- preview
jobs:
test_and_build:
runs-on: ubuntu-latest
steps:
- name: Check Out Code
uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v3
with:
node-version: '22'
- name: Install Dependencies
run: npm install
- name: Run Tests
run: npm run test
- name: Log in to GHCR
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin
- name: Build and Push Multi-Arch Docker Image
run: |
IMAGE_NAME="ghcr.io/${{ github.repository_owner }}/my-nextjs-app:${{ github.ref_name }}"
IMAGE_NAME=$(echo "$IMAGE_NAME" | tr '[:upper:]' '[:lower:]')
docker buildx create --use
docker buildx build \
--platform linux/arm64,linux/amd64 \
-t "$IMAGE_NAME" \
--push \
.
deploy:
runs-on: self-hosted
needs: test_and_build
steps:
- name: Check Out Code
uses: actions/checkout@v4
- name: Set Environment Variables
run: |
if [[ "${{ github.ref_name }}" == "production" ]]; then
echo "DEPLOY_ENV=production" >> $GITHUB_ENV
echo "PORT=4000" >> $GITHUB_ENV
elif [[ "${{ github.ref_name }}" == "dev" ]]; then
echo "DEPLOY_ENV=dev" >> $GITHUB_ENV
echo "PORT=4001" >> $GITHUB_ENV
elif [[ "${{ github.ref_name }}" == "preview" ]]; then
echo "DEPLOY_ENV=preview" >> $GITHUB_ENV
echo "PORT=4002" >> $GITHUB_ENV
fi
- name: Log in to GHCR
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin
- name: Pull Docker Image
run: |
IMAGE_NAME="ghcr.io/${{ github.repository_owner }}/my-nextjs-app:${{ github.ref_name }}"
IMAGE_NAME=$(echo "$IMAGE_NAME" | tr '[:upper:]' '[:lower:]')
docker pull "$IMAGE_NAME"
- name: Deploy on Raspberry Pi (Zero-Downtime)
run: |
IMAGE_NAME="ghcr.io/${{ github.repository_owner }}/my-nextjs-app:${{ github.ref_name }}"
IMAGE_NAME=$(echo "$IMAGE_NAME" | tr '[:upper:]' '[:lower:]')
CONTAINER_NAME="nextjs-$DEPLOY_ENV"
NEW_CONTAINER_NAME="$CONTAINER_NAME-new"
# Remove existing temporary container, if any
if [ "$(docker ps -aq -f name=$NEW_CONTAINER_NAME)" ]; then
docker rm -f "$NEW_CONTAINER_NAME" || true
fi
# Start new container on a temporary internal port
docker run -d --name "$NEW_CONTAINER_NAME" -p 40000:3000 \
-e GHOST_API_KEY="${{ secrets.GHOST_API_KEY }}" \
-e NEXT_PUBLIC_BASE_URL="${{ secrets.NEXT_PUBLIC_BASE_URL }}" \
-e MY_EMAIL="${{ secrets.MY_EMAIL }}" \
-e MY_PASSWORD="${{ secrets.MY_PASSWORD }}" \
-e GHOST_API_URL="${{ secrets.GHOST_API_URL }}" \
"$IMAGE_NAME"
# Wait for the new container to start
sleep 10
if [ "$(docker inspect --format='{{.State.Running}}' $NEW_CONTAINER_NAME)" = "true" ]; then
# Stop/remove the old container
if [ "$(docker ps -aq -f name=$CONTAINER_NAME)" ]; then
docker stop "$CONTAINER_NAME" || true
docker rm "$CONTAINER_NAME" || true
fi
# Replace the new container with final name/port
docker stop "$NEW_CONTAINER_NAME" || true
docker rm "$NEW_CONTAINER_NAME" || true
docker run -d --name "$CONTAINER_NAME" -p $PORT:3000 \
-e GHOST_API_KEY="${{ secrets.GHOST_API_KEY }}" \
-e NEXT_PUBLIC_BASE_URL="${{ secrets.NEXT_PUBLIC_BASE_URL }}" \
-e MY_EMAIL="${{ secrets.MY_EMAIL }}" \
-e MY_PASSWORD="${{ secrets.MY_PASSWORD }}" \
-e GHOST_API_URL="${{ secrets.GHOST_API_URL }}" \
"$IMAGE_NAME"
else
echo "New container failed to start."
docker logs "$NEW_CONTAINER_NAME"
exit 1
fi