Automation + package updates etc...
This commit is contained in:
parent
dd12f8b123
commit
42b8a6fd0e
3 changed files with 178 additions and 12 deletions
158
.forgejo/workflows/stagging.yml
Normal file
158
.forgejo/workflows/stagging.yml
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
# +=========================================================================================================================+
|
||||||
|
# | QA/Stagging CI/CD workflow |
|
||||||
|
# | |
|
||||||
|
# | Our QA/Stagging environment is hosted on servers in our office using a combination of: |
|
||||||
|
# | - Kubernetes (10 Ubuntu 24.04 VM nodes, hosted within a Proxmox VE cluster of 2 servers, a Dell R730xd and a Dell R730) |
|
||||||
|
# | - Nginx Proxy Manager as a reverse proxy |
|
||||||
|
# | - Pi-hole for DHCP |
|
||||||
|
# | - Bind for custom DNS |
|
||||||
|
# | On a cluster wide level: |
|
||||||
|
# | - Rook/Ceph |
|
||||||
|
# | - MetalLb |
|
||||||
|
# | - Nginx Ingress Controller |
|
||||||
|
# | - PosgreSQL Operator (CloudNativePG) |
|
||||||
|
# | - Custom PostgreSQL Database Operation (https://github.com/AlanBridgeman/postgres-controller) |
|
||||||
|
# | - MongoDB Community Operator |
|
||||||
|
# | On a namespace level: |
|
||||||
|
# | - Redis |
|
||||||
|
# | - Hasshicorp Vault |
|
||||||
|
# | - Mongo containers |
|
||||||
|
# | |
|
||||||
|
# | It's worth noting we largely use Helm to deploy resources into the cluster. |
|
||||||
|
# +=========================================================================================================================+
|
||||||
|
|
||||||
|
name: Build and deploy Harbor Helm Index to QA/Stagging (private Kubernetes cluster)
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- stagging
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write # Allows the workflow to push changes to the repository (e.g. for tagging)
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# Builds the codebase (builds the image)
|
||||||
|
build:
|
||||||
|
runs-on: self-hosted
|
||||||
|
outputs:
|
||||||
|
build_and_deploy: ${{ steps.version_check.outputs.build_and_deploy }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Prepare Environment Variables
|
||||||
|
run: |
|
||||||
|
echo "Harbor Username: ${{ secrets.HARBOR_USERNAME }}"
|
||||||
|
echo "HARBOR_USERNAME=${{ secrets.HARBOR_USERNAME }}" >> $GITHUB_ENV
|
||||||
|
echo "Harbor Password: ${{ secrets.HARBOR_PASSWORD }}"
|
||||||
|
echo "HARBOR_PASSWORD=${{ secrets.HARBOR_PASSWORD }}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
# Check if this is a "significant" commit that should trigger a build and deploy
|
||||||
|
# This is done by checking if the latest git tag matches the version in the `package.json` file
|
||||||
|
- name: Version Check
|
||||||
|
id: version_check
|
||||||
|
run: |
|
||||||
|
# Get the latest version from the `package.json` file
|
||||||
|
# This should be updated if a new build and deploy is desired
|
||||||
|
LATEST_VERSION=$(jq -r '.version' package.json)
|
||||||
|
echo "LATEST_VERSION=$LATEST_VERSION" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
# Get the latest Git tag from the repository
|
||||||
|
LATEST_TAG=$(git describe --tags --abbrev=0)
|
||||||
|
echo "LATEST_TAG=$LATEST_TAG" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
# If the git tag and the version ARE the same, this is a commit that SHOULD NOT trigger a build and deploy
|
||||||
|
# Inversely, if the git tag and the version are NOT the same, this is a commit that SHOULD trigger a build and deploy
|
||||||
|
if [[ "$LATEST_TAG" == "v$LATEST_VERSION" ]]; then
|
||||||
|
echo "Latest tag matches the version in package.json, SHOULD NOT build and deploy"
|
||||||
|
echo "build_and_deploy=false" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "Latest tag does not match the version in package.json, SHOULD build and deploy"
|
||||||
|
echo "build_and_deploy=true" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Conditional step to create a new Git tag
|
||||||
|
# This is required because when we go to build and deploy the image we rely on the latest git tag
|
||||||
|
# We do it this way so that ONLY situations where the git tag and the last built image are mal-aligned do we create a new tag
|
||||||
|
- name: Add Git Tag (if needed)
|
||||||
|
if: steps.version_check.outputs.build_and_deploy == 'true'
|
||||||
|
run: |
|
||||||
|
# Update remote URL to use the GITHUB_TOKEN for authentication
|
||||||
|
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@git.bridgemanaccessible.ca/${{ github.repository }}.git
|
||||||
|
|
||||||
|
# Setup git user details for committing the version change and tag
|
||||||
|
git config user.name "Forgejo Actions"
|
||||||
|
git config user.email "actions@git.bridgemanaccessible.ca"
|
||||||
|
|
||||||
|
# Create a new tag with the updated version number
|
||||||
|
git tag -a "v${{ env.LATEST_VERSION }}" -m "Version ${{ env.LATEST_VERSION }}"
|
||||||
|
|
||||||
|
# Push the new tag to the repository
|
||||||
|
git push --tags
|
||||||
|
|
||||||
|
# Run the build script found on self-hosted runner
|
||||||
|
- name: Run Build Image Script
|
||||||
|
if: steps.version_check.outputs.build_and_deploy == 'true'
|
||||||
|
run: |
|
||||||
|
CURR_DIR="$PWD"
|
||||||
|
|
||||||
|
# Change into the repository directory
|
||||||
|
cd "$GITHUB_WORKSPACE"
|
||||||
|
|
||||||
|
IMAGE_TAG=$(git describe --tags --abbrev=0) # Use the most recent tag as the image tag
|
||||||
|
IMAGE_FULL_NAME="containers.bridgemanaccessible.ca/k8s/${IMAGE_NAME}:${IMAGE_TAG}"
|
||||||
|
|
||||||
|
echo "🔹 Building and pushing image..."
|
||||||
|
docker build -t ${IMAGE_FULL_NAME} .
|
||||||
|
docker login -u $HARBOR_USERNAME -p $HARBOR_PASSWORD containers.bridgemanaccessible.ca
|
||||||
|
docker push ${IMAGE_FULL_NAME}
|
||||||
|
|
||||||
|
cd "$CURR_DIR"
|
||||||
|
|
||||||
|
echo "✅ Build successful!"
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
runs-on: self-hosted
|
||||||
|
needs: build
|
||||||
|
if: needs.build.outputs.build_and_deploy == 'true'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Get the latest tag
|
||||||
|
id: get_latest_tag
|
||||||
|
run: |
|
||||||
|
LATEST_TAG=$(git describe --tags --abbrev=0)
|
||||||
|
echo "LATEST_TAG=$LATEST_TAG" >> $GITHUB_ENV
|
||||||
|
echo "IMAGE_VERSION=${LATEST_TAG#v}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
#- name: Prepare Environment Variables
|
||||||
|
# run: |
|
||||||
|
# echo "HARBOR_USERNAME=${{ secrets.HARBOR_USERNAME }}" >> $GITHUB_ENV
|
||||||
|
# echo "HARBOR_PASSWORD=${{ secrets.HARBOR_PASSWORD }}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Run Deploy Kubernetes Script
|
||||||
|
run: |
|
||||||
|
IMAGE_VERSION="${{ env.IMAGE_VERSION }}"
|
||||||
|
NAMESPACE="harbor-helm-index"
|
||||||
|
DEPLOYMENT_NAME="helm-index"
|
||||||
|
CONTAINER_NAME="helm-index"
|
||||||
|
IMAGE_NAME="harbor-helm-index"
|
||||||
|
|
||||||
|
echo "Image Version: $IMAGE_VERSION"
|
||||||
|
echo "Namespace: $NAMESPACE"
|
||||||
|
echo "Deployment Name: $DEPLOYMENT_NAME"
|
||||||
|
echo "Container Name: $CONTAINER_NAME"
|
||||||
|
echo "Image Name: $IMAGE_NAME"
|
||||||
|
|
||||||
|
update-k8s-deployment-image \
|
||||||
|
--image-version $IMAGE_VERSION \
|
||||||
|
--namespace $NAMESPACE \
|
||||||
|
--deployment-name $DEPLOYMENT_NAME \
|
||||||
|
--container-name $CONTAINER_NAME \
|
||||||
|
--image-name "containers.bridgemanaccessible.ca/k8s/$IMAGE_NAME"
|
||||||
|
|
@ -29,6 +29,5 @@
|
||||||
"pg": "^8.13.3",
|
"pg": "^8.13.3",
|
||||||
"typeorm": "^0.3.20",
|
"typeorm": "^0.3.20",
|
||||||
"uuid": "^11.0.5"
|
"uuid": "^11.0.5"
|
||||||
},
|
}
|
||||||
"packageManager": "yarn@1.22.22"
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { Application } from 'express';
|
|
||||||
import { App, Initializer, globalTemplateValues } from '@BridgemanAccessible/ba-web-framework';
|
import { App, Initializer, globalTemplateValues } from '@BridgemanAccessible/ba-web-framework';
|
||||||
|
|
||||||
import { createConn } from './utils/db';
|
import { createConn } from './utils/db';
|
||||||
|
|
@ -20,20 +19,30 @@ async function createInitialDatabaseConnection() {
|
||||||
await createConn('postgres', connOptions);
|
await createConn('postgres', connOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onStart(app: Application) {
|
async function onStart(app: App) {
|
||||||
// Create the initial database connection
|
// Create the initial database connection
|
||||||
createInitialDatabaseConnection();
|
createInitialDatabaseConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
await new App().run(new Initializer({
|
await new App().run(
|
||||||
|
new Initializer(
|
||||||
|
{
|
||||||
controllersPath: path.join(__dirname, 'routes'),
|
controllersPath: path.join(__dirname, 'routes'),
|
||||||
staticFilesPath: path.join(__dirname, 'static'),
|
staticFilesPath: path.join(__dirname, 'static'),
|
||||||
view: {
|
view: {
|
||||||
engine: 'ejs',
|
engine: 'ejs',
|
||||||
filesPath: path.join(__dirname, 'pages')
|
filesPath: path.join(__dirname, 'pages')
|
||||||
}
|
}
|
||||||
}, globalTemplateValues({ company: process.env.COMPANY, titleSuffix: process.env.WEBSITE_TITLE_SUFFIX, hostname: process.env.HOSTNAME })), onStart);
|
},
|
||||||
|
globalTemplateValues({
|
||||||
|
company: process.env.COMPANY,
|
||||||
|
titleSuffix: process.env.WEBSITE_TITLE_SUFFIX,
|
||||||
|
hostname: process.env.HOSTNAME
|
||||||
|
})
|
||||||
|
),
|
||||||
|
onStart
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
main()
|
main()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue