mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-01-05 21:03:24 -05:00
feat(deployments): build and deploy the stack
This commit is contained in:
43
.github/workflows/build-images.yml
vendored
43
.github/workflows/build-images.yml
vendored
@@ -1,43 +0,0 @@
|
||||
name: CI - Build Images
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build (Image)
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [20.x]
|
||||
apps: [api]
|
||||
site_tlds: [dev, org]
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- name: Checkout Source Files
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Create a tagname
|
||||
id: tagname
|
||||
run: |
|
||||
echo "tagname=$(git rev-parse --short HEAD)-$(date +%Y%m%d)-$(date +%H%M)" >> $GITHUB_ENV
|
||||
|
||||
- name: Build & Tag Image
|
||||
run: |
|
||||
docker build \
|
||||
--tag registry.digitalocean.com/${{ secrets.DOCR_NAME }}/${{ matrix.site_tlds }}/learn-${{ matrix.apps }}:$tagname \
|
||||
--tag registry.digitalocean.com/${{ secrets.DOCR_NAME }}/${{ matrix.site_tlds }}/learn-${{ matrix.apps }}:latest \
|
||||
--file docker/${{ matrix.apps }}/Dockerfile .
|
||||
|
||||
- name: Install doctl
|
||||
uses: digitalocean/action-doctl@v2
|
||||
with:
|
||||
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
|
||||
|
||||
- name: Log in to DigitalOcean Container Registry with short-lived credentials
|
||||
run: doctl registry login --expiry-seconds 1200
|
||||
|
||||
- name: Push image to DigitalOcean Container Registry
|
||||
run: |
|
||||
docker push registry.digitalocean.com/${{ secrets.DOCR_NAME }}/${{ matrix.site_tlds }}/learn-${{ matrix.apps }}:$tagname
|
||||
docker push registry.digitalocean.com/${{ secrets.DOCR_NAME }}/${{ matrix.site_tlds }}/learn-${{ matrix.apps }}:latest
|
||||
100
.github/workflows/deploy.yml
vendored
Normal file
100
.github/workflows/deploy.yml
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
name: CD -- Deploy - API (Docker Swarm)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
static:
|
||||
runs-on: ubuntu-24.04
|
||||
outputs:
|
||||
site_tld: ${{ steps.static_data.outputs.site_tld }}
|
||||
environment: ${{ steps.static_data.outputs.environment }}
|
||||
|
||||
steps:
|
||||
- name: Set site_tld
|
||||
id: static_data
|
||||
run: |
|
||||
if [ "${{ github.ref }}" == "refs/heads/prod-staging" ]; then
|
||||
echo "site_tld=dev" >> $GITHUB_OUTPUT
|
||||
echo "environment=staging" >> $GITHUB_OUTPUT
|
||||
elif [ "${{ github.ref }}" == "refs/heads/prod-current" ]; then
|
||||
echo "site_tld=org" >> $GITHUB_OUTPUT
|
||||
echo "environment=production" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "site_tld=dev" >> $GITHUB_OUTPUT
|
||||
echo "environment=staging" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
build:
|
||||
name: Build & Push Docker Image
|
||||
needs: static
|
||||
uses: ./.github/workflows/re--docker-docr.yml
|
||||
with:
|
||||
site_tld: ${{ needs.static.outputs.site_tld }}
|
||||
app: api
|
||||
|
||||
deploy:
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [static, build]
|
||||
permissions:
|
||||
deployments: write
|
||||
environment:
|
||||
name: ${{ needs.static.outputs.environment }}
|
||||
url: https://api.freecodecamp.${{ needs.static.outputs.site_tld }}/status/ping?version=${{ needs.build.outputs.tagname }}
|
||||
|
||||
steps:
|
||||
- name: Setup and connect to Tailscale network
|
||||
uses: tailscale/github-action@v3
|
||||
with:
|
||||
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
|
||||
oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
|
||||
tags: tag:ci
|
||||
version: latest
|
||||
|
||||
- name: Configure SSH
|
||||
# This is a workaround to avoid the SSH warning about known hosts & strict host key checking.
|
||||
# It's not a problem for us, because we're using Tailscale to connect.
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo "Host *
|
||||
UserKnownHostsFile=/dev/null
|
||||
StrictHostKeyChecking no" > ~/.ssh/config
|
||||
|
||||
- name: Check connection to Deployment Target
|
||||
run: |
|
||||
tailscale status | grep -q "$TS_MACHINE_NAME" || { echo "Machine not found"; exit 1; }
|
||||
ssh $TS_USERNAME@$TS_MACHINE_NAME "uptime"
|
||||
|
||||
- name: Deploy with Docker Stack
|
||||
env:
|
||||
STACK_NAME: stg-api
|
||||
RUNTIME_ENVS: ${{ secrets.RUNTIME_ENVS }}
|
||||
DEPLOYMENT_VERSION: ${{ needs.build.outputs.tagname }}
|
||||
run: |
|
||||
REMOTE_USER=$TS_USERNAME
|
||||
ssh $TS_USERNAME@$TS_MACHINE_NAME /bin/bash << EOF
|
||||
|
||||
# Change to the config directory
|
||||
cd /home/${REMOTE_USER}/docker-swarm-config/stacks/api || exit 1
|
||||
echo "Debug: Current directory: \$(pwd)"
|
||||
|
||||
# Create temp file for the environment variables
|
||||
echo "${RUNTIME_ENVS}" > .env.tmp
|
||||
echo "DEPLOYMENT_VERSION=${DEPLOYMENT_VERSION}" >> .env.tmp
|
||||
|
||||
# Source the environment variables
|
||||
set -a # Automatically export all variables
|
||||
source .env.tmp || exit 1
|
||||
set +a
|
||||
|
||||
# Clean up the temp file
|
||||
rm -f .env.tmp
|
||||
|
||||
# Verify the environment variables
|
||||
echo "Debug: Sanity check variables: "
|
||||
env | grep -E '^DEPLOYMENT' || echo 'Vars not found'
|
||||
echo "Debug: Sanity check config: "
|
||||
docker stack config -c stack-api.yml | rg 'DOMAIN' || echo 'Config not found'
|
||||
|
||||
EOF
|
||||
shell: bash
|
||||
72
.github/workflows/docker-docr.yml
vendored
Normal file
72
.github/workflows/docker-docr.yml
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
name: Docker -- DOCR
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
site_tld:
|
||||
required: true
|
||||
type: choice
|
||||
description: 'Input: The site tld (variant) to build'
|
||||
options:
|
||||
- dev
|
||||
- org
|
||||
default: 'dev'
|
||||
app:
|
||||
required: true
|
||||
type: string
|
||||
description: 'Input: The app (component) to build'
|
||||
default: 'api'
|
||||
workflow_call:
|
||||
inputs:
|
||||
site_tld:
|
||||
required: true
|
||||
type: string
|
||||
description: 'Input: The site tld (variant) to build'
|
||||
app:
|
||||
required: true
|
||||
type: string
|
||||
description: 'Input: The app (component) to build'
|
||||
outputs:
|
||||
tagname:
|
||||
description: 'Output: The tagname for the image built'
|
||||
value: ${{ jobs.build.outputs.tagname }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build (Image)
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
tagname: ${{ steps.tagname.outputs.tagname }}
|
||||
|
||||
steps:
|
||||
- name: Checkout Source Files
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Create a tagname
|
||||
id: tagname
|
||||
run: |
|
||||
tagname=$(git rev-parse --short HEAD)-$(date +%Y%m%d)-$(date +%H%M)
|
||||
echo "tagname=$tagname" >> $GITHUB_ENV
|
||||
echo "tagname=$tagname" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Build & Tag Image
|
||||
run: |
|
||||
docker build \
|
||||
--tag registry.digitalocean.com/${{ secrets.DOCR_NAME }}/${{ inputs.site_tld }}/learn-${{ inputs.app }}:$tagname \
|
||||
--tag registry.digitalocean.com/${{ secrets.DOCR_NAME }}/${{ inputs.site_tld }}/learn-${{ inputs.app }}:latest \
|
||||
--file docker/${{ inputs.app }}/Dockerfile .
|
||||
|
||||
- name: Install doctl
|
||||
uses: digitalocean/action-doctl@v2
|
||||
with:
|
||||
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
|
||||
|
||||
- name: Log in to DigitalOcean Container Registry with short-lived credentials
|
||||
run: doctl registry login --expiry-seconds 1200
|
||||
|
||||
- name: Push image to DigitalOcean Container Registry
|
||||
run: |
|
||||
docker push registry.digitalocean.com/${{ secrets.DOCR_NAME }}/${{ inputs.site_tld }}/learn-${{ inputs.app }}:$tagname
|
||||
docker push registry.digitalocean.com/${{ secrets.DOCR_NAME }}/${{ inputs.site_tld }}/learn-${{ inputs.app }}:latest
|
||||
Reference in New Issue
Block a user