mirror of
https://github.com/Novaloop-AG/healthchat-web.git
synced 2026-10-31 08:15:07 +00:00
201 lines
8.2 KiB
YAML
201 lines
8.2 KiB
YAML
name: Release HealthChat
|
|
|
|
# Tag-driven release pipeline for HealthChat builds of element-web.
|
|
# Mirrors ../element-ios/.github/workflows/release-healthchat.yml.
|
|
# Runbook: .claude/skills/releasing-healthchat/SKILL.md
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- "healthchat-v*"
|
|
workflow_dispatch:
|
|
inputs:
|
|
version:
|
|
description: "Version (e.g. 1.4.0). Required when running manually."
|
|
required: true
|
|
type: string
|
|
workspace_ref:
|
|
description: "Override healthchat-workspace ref (defaults to .healthchat-workspace-version)."
|
|
required: false
|
|
type: string
|
|
release_notes_override:
|
|
description: "Optional release notes; falls back to HEALTHCHAT_CHANGES.md section for the given version."
|
|
required: false
|
|
type: string
|
|
|
|
permissions:
|
|
contents: write # create GitHub Release
|
|
packages: write # push Docker image
|
|
id-token: write # attestations
|
|
attestations: write
|
|
|
|
concurrency:
|
|
group: release-healthchat-${{ github.event.inputs.version || github.ref_name }}
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
release:
|
|
name: Build & publish HealthChat image
|
|
runs-on: ubuntu-latest
|
|
env:
|
|
DOCKER_REGISTRY: "ghcr.io"
|
|
DOCKER_IMAGE: ${{ format('{0}/healthchat-web', github.repository) }}
|
|
DOCKER_PUSH: true
|
|
DOCKER_SIGNING: false
|
|
FORCE_COLOR: 1
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Resolve version
|
|
id: version
|
|
run: |
|
|
set -euo pipefail
|
|
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
|
VERSION="${{ github.event.inputs.version }}"
|
|
else
|
|
VERSION="${GITHUB_REF_NAME#healthchat-v}"
|
|
fi
|
|
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z.-]+)?$ ]]; then
|
|
echo "::error::Invalid version '$VERSION' — expected e.g. 1.4.0 or 1.4.0-rc1"
|
|
exit 1
|
|
fi
|
|
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
# `:latest` is what the ansible inventory deploys from, so only a clean
|
|
# X.Y.Z tag push may move it — never an -rc/-hotfix/-dryrun tag, and never
|
|
# a manual re-run. Otherwise a release candidate or a pipeline test would
|
|
# become production on the next deploy of any kind.
|
|
if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ && "$GITHUB_EVENT_NAME" == "push" ]]; then
|
|
IS_STABLE=true
|
|
else
|
|
IS_STABLE=false
|
|
fi
|
|
echo "is_stable=$IS_STABLE" >> "$GITHUB_OUTPUT"
|
|
echo "Resolved version: $VERSION (moves :latest: $IS_STABLE)"
|
|
|
|
- name: Resolve workspace ref
|
|
id: workspace
|
|
env:
|
|
OVERRIDE: ${{ github.event.inputs.workspace_ref }}
|
|
run: |
|
|
set -euo pipefail
|
|
if [[ -n "$OVERRIDE" ]]; then
|
|
REF="$OVERRIDE"
|
|
echo "Using workspace ref from workflow input: $REF"
|
|
elif [[ -f .healthchat-workspace-version ]]; then
|
|
REF=$(head -n1 .healthchat-workspace-version | tr -d '[:space:]')
|
|
if [[ -z "$REF" ]]; then
|
|
echo "::error::.healthchat-workspace-version is empty"
|
|
exit 1
|
|
fi
|
|
echo "Using workspace ref from .healthchat-workspace-version: $REF"
|
|
else
|
|
echo "::error::.healthchat-workspace-version missing and no workspace_ref override provided"
|
|
exit 1
|
|
fi
|
|
echo "ref=$REF" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Extract release notes
|
|
id: notes
|
|
env:
|
|
VERSION: ${{ steps.version.outputs.version }}
|
|
OVERRIDE: ${{ github.event.inputs.release_notes_override }}
|
|
run: |
|
|
set -euo pipefail
|
|
if [[ -n "$OVERRIDE" ]]; then
|
|
NOTES="$OVERRIDE"
|
|
echo "Using release notes from workflow input"
|
|
else
|
|
NOTES=$(awk -v ver="$VERSION" '
|
|
/^## Changes in / {
|
|
if (found) { exit }
|
|
if ($0 ~ "## Changes in " ver "( |$|\\()") { found = 1; next }
|
|
}
|
|
found { print }
|
|
' HEALTHCHAT_CHANGES.md | sed '/^[[:space:]]*$/{N;/^\n$/D;}')
|
|
if [[ -z "$NOTES" ]]; then
|
|
NOTES="HealthChat ${VERSION} — automated build from ${GITHUB_REF_NAME}."
|
|
echo "::warning::No HEALTHCHAT_CHANGES.md section found for $VERSION — using fallback"
|
|
fi
|
|
fi
|
|
{
|
|
echo 'notes<<NOTES_EOF'
|
|
echo "$NOTES"
|
|
echo 'NOTES_EOF'
|
|
} >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Checkout healthchat-workspace
|
|
uses: actions/checkout@v4
|
|
with:
|
|
repository: Novaloop-AG/healthchat-workspace
|
|
path: healthchat-workspace
|
|
token: ${{ secrets.HEALTHCHAT_WORKSPACE_TOKEN }}
|
|
ref: ${{ steps.workspace.outputs.ref }}
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
|
|
- name: Build element-plugin
|
|
run: |
|
|
cd healthchat-workspace/element-plugin
|
|
npm ci
|
|
npm run build
|
|
cd module
|
|
npm ci
|
|
npm run build
|
|
|
|
- name: Stage plugin artifacts for Docker
|
|
run: |
|
|
mkdir -p plugin-dist/elements
|
|
cp healthchat-workspace/element-plugin/module/dist/healthchat-module.js plugin-dist/healthchat-module.js
|
|
cp healthchat-workspace/element-plugin/dist/elements/browser/main.js plugin-dist/elements/healthchat-elements.js
|
|
|
|
- name: Log in to the Github Container registry
|
|
uses: docker/login-action@v3
|
|
with:
|
|
registry: ${{ env.DOCKER_REGISTRY }}
|
|
username: ${{ github.actor }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Extract metadata (tags, labels) for Docker
|
|
id: metadata
|
|
uses: docker/metadata-action@v5
|
|
with:
|
|
images: ${{ env.DOCKER_REGISTRY }}/${{ env.DOCKER_IMAGE }}
|
|
tags: |
|
|
type=raw,value=${{ steps.version.outputs.version }}
|
|
type=raw,value=latest,enable=${{ steps.version.outputs.is_stable == 'true' }}
|
|
type=raw,value=${{ github.sha }}
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
|
|
- name: Build and push Docker images
|
|
id: push
|
|
uses: docker/build-push-action@v6
|
|
with:
|
|
context: .
|
|
file: ./apps/web/Dockerfile
|
|
push: ${{ env.DOCKER_PUSH }}
|
|
tags: ${{ steps.metadata.outputs.tags }}
|
|
labels: ${{ steps.metadata.outputs.labels }}
|
|
|
|
- name: Generate artifact attestation
|
|
if: ${{ env.DOCKER_SIGNING == 'true' }}
|
|
uses: actions/attest-build-provenance@v1
|
|
with:
|
|
subject-name: ${{ env.DOCKER_REGISTRY }}/${{ env.DOCKER_IMAGE }}
|
|
subject-digest: ${{ steps.push.outputs.digest }}
|
|
push-to-registry: ${{ env.DOCKER_PUSH }}
|
|
|
|
- name: Create GitHub Release
|
|
if: github.event_name == 'push'
|
|
uses: softprops/action-gh-release@v2
|
|
with:
|
|
tag_name: ${{ github.ref_name }}
|
|
name: HealthChat ${{ steps.version.outputs.version }}
|
|
body: ${{ steps.notes.outputs.notes }}
|