Skip to content

fix(admin): run refresh handler by ID via request body (#96) #68

fix(admin): run refresh handler by ID via request body (#96)

fix(admin): run refresh handler by ID via request body (#96) #68

name: Build & Push Core Images
on:
workflow_dispatch:
push:
branches: [main]
paths:
- 'server/**'
- 'modules/**'
- 'shared/**'
- 'src/**'
- 'deploy/core.*.Dockerfile'
- 'deploy/nginx-default.conf'
- 'deploy/openshift/base/**'
- 'package*.json'
- 'vite.config.mjs'
- 'tailwind.config.mjs'
- 'postcss.config.mjs'
- 'index.html'
- 'tests/smoke/**'
- 'playwright.config.js'
- 'services/chatbot/**'
- 'deploy/certs/**'
permissions:
contents: read
concurrency:
group: build-images-${{ github.ref_name }}
cancel-in-progress: true
env:
CORE_BACKEND_IMAGE: quay.io/org-pulse/org-pulse-core-backend
CORE_FRONTEND_IMAGE: quay.io/org-pulse/org-pulse-core-frontend
CHATBOT_IMAGE: quay.io/org-pulse/org-pulse-chatbot
jobs:
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: '22'
cache: 'npm'
- run: npm ci
- run: npm run lint
- run: npm test
- run: npm run build
build-core-backend:
name: Build Core Backend
needs: [test]
runs-on: ubuntu-latest
env:
BUILD_SHA: ${{ github.sha }}
steps:
- uses: actions/checkout@v7
- name: Build core backend image
run: |
docker build \
-f deploy/core.backend.Dockerfile \
--build-arg GIT_SHA=${BUILD_SHA} \
--build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \
-t ${{ env.CORE_BACKEND_IMAGE }}:${BUILD_SHA} \
.
- name: Smoke test core backend
run: |
docker run -d --name core-backend-smoke -p 3001:3001 \
-e DEMO_MODE=true \
${{ env.CORE_BACKEND_IMAGE }}:${BUILD_SHA}
echo "Waiting for core backend to start..."
sleep 5
if curl -sf --max-time 5 http://localhost:3001/api/healthz > /dev/null 2>&1; then
echo "Core backend smoke test passed"
else
echo "Core backend smoke test failed"
docker logs core-backend-smoke
docker stop core-backend-smoke
exit 1
fi
docker stop core-backend-smoke
- name: Save image artifact
run: docker save ${{ env.CORE_BACKEND_IMAGE }}:${BUILD_SHA} -o /tmp/core-backend.tar
- name: Upload image artifact
uses: actions/upload-artifact@v7
with:
name: core-backend-image
path: /tmp/core-backend.tar
retention-days: 1
build-core-frontend:
name: Build Core Frontend
needs: [test]
runs-on: ubuntu-latest
env:
BUILD_SHA: ${{ github.sha }}
steps:
- uses: actions/checkout@v7
- name: Build core frontend image
run: |
docker build \
-f deploy/core.frontend.Dockerfile \
-t ${{ env.CORE_FRONTEND_IMAGE }}:${BUILD_SHA} \
.
- name: Save image artifact
run: docker save ${{ env.CORE_FRONTEND_IMAGE }}:${BUILD_SHA} -o /tmp/core-frontend.tar
- name: Upload image artifact
uses: actions/upload-artifact@v7
with:
name: core-frontend-image
path: /tmp/core-frontend.tar
retention-days: 1
build-core-frontend-builder:
name: Build Core Frontend Builder
needs: [test]
runs-on: ubuntu-latest
env:
BUILD_SHA: ${{ github.sha }}
steps:
- uses: actions/checkout@v7
- name: Build core frontend builder image
run: |
docker build \
-f deploy/core.frontend-builder.Dockerfile \
-t ${{ env.CORE_FRONTEND_IMAGE }}-builder:${BUILD_SHA} \
.
- name: Save image artifact
run: docker save ${{ env.CORE_FRONTEND_IMAGE }}-builder:${BUILD_SHA} -o /tmp/core-frontend-builder.tar
- name: Upload image artifact
uses: actions/upload-artifact@v7
with:
name: core-frontend-builder-image
path: /tmp/core-frontend-builder.tar
retention-days: 1
build-core-frontend-runtime:
name: Build Core Frontend Runtime
needs: [test]
runs-on: ubuntu-latest
env:
BUILD_SHA: ${{ github.sha }}
steps:
- uses: actions/checkout@v7
- name: Build core frontend runtime image
run: |
docker build \
-f deploy/core.frontend-runtime.Dockerfile \
-t ${{ env.CORE_FRONTEND_IMAGE }}-runtime:${BUILD_SHA} \
.
- name: Save image artifact
run: docker save ${{ env.CORE_FRONTEND_IMAGE }}-runtime:${BUILD_SHA} -o /tmp/core-frontend-runtime.tar
- name: Upload image artifact
uses: actions/upload-artifact@v7
with:
name: core-frontend-runtime-image
path: /tmp/core-frontend-runtime.tar
retention-days: 1
build-chatbot:
name: Build Chatbot
needs: [test]
runs-on: ubuntu-latest
env:
BUILD_SHA: ${{ github.sha }}
steps:
- uses: actions/checkout@v7
- name: Copy internal CA into build context
run: cp deploy/certs/internal-root-ca.pem services/chatbot/internal-root-ca.pem
- name: Build chatbot image
run: |
docker build \
-f services/chatbot/Containerfile \
--build-arg GIT_SHA=${BUILD_SHA} \
--build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \
-t ${{ env.CHATBOT_IMAGE }}:${BUILD_SHA} \
services/chatbot
- name: Smoke test chatbot
run: |
docker run -d --name chatbot-smoke -p 8002:8002 \
-e CHATBOT_LLM_BASE_URL=http://localhost:9999/v1 \
-e CHATBOT_LLM_API_KEY=test \
${{ env.CHATBOT_IMAGE }}:${BUILD_SHA}
echo "Waiting for chatbot to start..."
sleep 5
if curl -sf --max-time 5 http://localhost:8002/health > /dev/null 2>&1; then
echo "Chatbot smoke test passed"
else
echo "Chatbot smoke test failed"
docker logs chatbot-smoke
docker stop chatbot-smoke
exit 1
fi
docker stop chatbot-smoke
- name: Save image artifact
run: docker save ${{ env.CHATBOT_IMAGE }}:${BUILD_SHA} -o /tmp/chatbot.tar
- name: Upload image artifact
uses: actions/upload-artifact@v7
with:
name: chatbot-image
path: /tmp/chatbot.tar
retention-days: 1
smoke-test-core:
name: Core Smoke Tests
needs: [build-core-backend, build-core-frontend]
runs-on: ubuntu-latest
env:
BUILD_SHA: ${{ github.sha }}
steps:
- uses: actions/checkout@v7
- name: Download backend image
uses: actions/download-artifact@v8
with:
name: core-backend-image
path: /tmp
- name: Download frontend image
uses: actions/download-artifact@v8
with:
name: core-frontend-image
path: /tmp
- name: Load images
run: |
docker load -i /tmp/core-backend.tar
docker load -i /tmp/core-frontend.tar
- name: Run smoke tests against core images
run: |
make smoke-test-core \
CONTAINER_RUNTIME=docker \
CORE_BACKEND_IMAGE=${{ env.CORE_BACKEND_IMAGE }}:${BUILD_SHA} \
CORE_FRONTEND_IMAGE=${{ env.CORE_FRONTEND_IMAGE }}:${BUILD_SHA}
release:
name: Release
needs: [smoke-test-core, build-core-backend, build-core-frontend, build-core-frontend-builder, build-core-frontend-runtime, build-chatbot]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
outputs:
version: ${{ steps.bump.outputs.version }}
release_sha: ${{ steps.bump.outputs.release_sha }}
env:
BUILD_SHA: ${{ github.sha }}
steps:
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@v3
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- uses: actions/checkout@v7
with:
ref: main
token: ${{ steps.app-token.outputs.token }}
- uses: actions/setup-node@v7
with:
node-version: '22'
- name: Bump patch version
id: bump
run: |
CURRENT=$(node -p "require('./package.json').version")
NEW=$(npm version patch --no-git-tag-version)
while git ls-remote --tags origin "refs/tags/${NEW}" | grep -q .; do
echo "Tag ${NEW} already exists, bumping again..."
NEW=$(npm version patch --no-git-tag-version)
done
echo "Bumped ${CURRENT} -> ${NEW}"
echo "version=${NEW}" >> "$GITHUB_OUTPUT"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add package.json package-lock.json
git commit -m "release: ${NEW} [skip ci]"
echo "release_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
- name: Download all image artifacts
uses: actions/download-artifact@v8
with:
path: /tmp/images
- name: Load all images
run: |
docker load -i /tmp/images/core-backend-image/core-backend.tar
docker load -i /tmp/images/core-frontend-image/core-frontend.tar
docker load -i /tmp/images/core-frontend-builder-image/core-frontend-builder.tar
docker load -i /tmp/images/core-frontend-runtime-image/core-frontend-runtime.tar
docker load -i /tmp/images/chatbot-image/chatbot.tar
- name: Login to Quay.io
uses: docker/login-action@v4
with:
registry: quay.io
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}
- name: Push all images
env:
VERSION: ${{ steps.bump.outputs.version }}
run: |
for IMAGE in \
"${{ env.CORE_BACKEND_IMAGE }}" \
"${{ env.CORE_FRONTEND_IMAGE }}" \
"${{ env.CHATBOT_IMAGE }}" \
"${{ env.CORE_FRONTEND_IMAGE }}-builder" \
"${{ env.CORE_FRONTEND_IMAGE }}-runtime"; do
docker tag "${IMAGE}:${BUILD_SHA}" "${IMAGE}:latest"
docker tag "${IMAGE}:${BUILD_SHA}" "${IMAGE}:${VERSION}"
docker push "${IMAGE}:${BUILD_SHA}"
docker push "${IMAGE}:latest"
docker push "${IMAGE}:${VERSION}"
done
- name: Install kustomize
uses: imranismail/setup-kustomize@v3
with:
kustomize-version: '5.8.1'
- name: Update deploy image tags
working-directory: deploy/openshift/base
run: |
kustomize edit set image ${{ env.CORE_BACKEND_IMAGE }}:${BUILD_SHA}
kustomize edit set image ${{ env.CORE_FRONTEND_IMAGE }}:${BUILD_SHA}
kustomize edit set image ${{ env.CHATBOT_IMAGE }}:${BUILD_SHA}
- name: Validate kustomize build
run: kustomize build deploy/openshift/base > /dev/null
- name: Commit deploy update, tag, and push
env:
VERSION: ${{ steps.bump.outputs.version }}
run: |
git add deploy/openshift/base/kustomization.yaml
git diff --cached --quiet && { echo "No deploy changes to commit"; } || \
git commit -m "deploy: update backend + frontend + chatbot image to ${VERSION} (${BUILD_SHA}) [skip ci]"
git tag "${VERSION}"
git push origin main --tags
- name: Create GitHub Release
uses: softprops/action-gh-release@v3
with:
tag_name: ${{ steps.bump.outputs.version }}
generate_release_notes: true
token: ${{ steps.app-token.outputs.token }}
publish-package:
name: Publish npm Package
needs: [release]
runs-on: ubuntu-latest
environment: npm-publish
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v7
with:
ref: ${{ needs.release.outputs.release_sha }}
- uses: actions/setup-node@v7
with:
node-version: '22'
registry-url: 'https://registry.npmjs.org'
- run: npm install -g npm@11.17.0
- run: npm ci
- name: Publish
run: npm publish --provenance --access public