Files
hiveops-guide/.gitea/workflows/cd-develop.yml
T
johannes e1fcd4c00b fix(guide-ci): make Slack notify step non-fatal + reachability probe
The Notify Slack step could fail the whole job (turning a successful deploy
red, as just happened). A notification must never fail a deploy:
- continue-on-error: true on the step
- curl captures HTTP code and never propagates a non-zero exit (|| echo)
- logs "slack notify HTTP: <code>" so we can see if the runner reaches Slack
- first commit line via ${VAR%%$'\n'*} param-expansion (no head pipe)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 14:20:32 -04:00

114 lines
5.9 KiB
YAML

name: CD - Develop (guide → bcos.dev)
# Guide-specific CI (issue #5). The guide bundles markdown INTO the backend jar at build time,
# so a running instance must be rebuilt + redeployed to pick up content changes — a git-pull is
# not enough. This automates that on every push to develop: build → push :dev → deploy to bcos.dev.
#
# Auto-deploy is intentional and scoped to the DEV environment only (docs, low blast radius).
# Audience filtering is runtime (GUIDE_SERVED_AUDIENCES): bcos.dev serves all four tiers; prod
# (a future cd-main, gated) serves only customer,internal — so dev/bcos content never leaves dev.
# Auto-deploy live: BCOS_DEV_DEPLOY_KEY provisioned (scoped forced-command key on .251).
on:
push:
branches:
- develop
paths:
- 'backend/**'
- '.gitea/workflows/cd-develop.yml'
jobs:
build-and-deploy:
runs-on: ubuntu-latest
env:
GIT_SSL_NO_VERIFY: "true"
MAVEN_OPTS: "-Djava.net.preferIPv4Stack=true -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true"
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Configure Maven settings (Gitea package registry)
run: |
mkdir -p ~/.m2
cat > ~/.m2/settings.xml << 'EOF'
<settings>
<servers>
<server><id>gitea</id><username>hiveiq</username><password>${{ secrets.MAVEN_TOKEN }}</password></server>
</servers>
<profiles>
<profile>
<id>gitea-registry</id>
<repositories>
<repository>
<id>gitea</id>
<url>https://hiveiq-gitea.directlx.dev/api/packages/hiveops/maven</url>
<releases><enabled>true</enabled></releases><snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles><activeProfile>gitea-registry</activeProfile></activeProfiles>
</settings>
EOF
# mvn package FIRST — the Dockerfile does `COPY target/*.jar`, so skipping this ships stale
# content (the exact trap that makes the manual process error-prone).
- name: Build backend JAR (bakes in content)
run: cd backend && mvn clean package -DskipTests -B
- name: Build + push image
run: |
echo "${{ secrets.DEV_REGISTRY_PASSWORD }}" | docker login ${{ secrets.DEV_REGISTRY_URL }} -u ${{ secrets.DEV_REGISTRY_USERNAME }} --password-stdin
docker build -t ${{ secrets.DEV_REGISTRY_URL }}/hiveiq-guide-backend:dev backend/
docker push ${{ secrets.DEV_REGISTRY_URL }}/hiveiq-guide-backend:dev
# DEPENDENCY (issue #5, coordinate with CI/runner session): needs BCOS_DEV_DEPLOY_KEY secret
# (SSH key for bcosadmin@.251) + runner network reachability to 173.231.195.251.
- name: Deploy to bcos.dev
run: |
mkdir -p ~/.ssh && echo "${{ secrets.BCOS_DEV_DEPLOY_KEY }}" > ~/.ssh/dk && chmod 600 ~/.ssh/dk
ssh -i ~/.ssh/dk -o StrictHostKeyChecking=no bcosadmin@173.231.195.251 \
'cd ~/hiveiq/hiveops-openmetal/hiveops/instances/dev && docker compose pull hiveiq-guide-backend && docker compose up -d hiveiq-guide-backend'
- name: Smoke — guide backend healthy + content served
run: |
for i in $(seq 1 12); do
s=$(curl -sk -o /dev/null -w '%{http_code}' https://api.bcos.dev/guide/actuator/health || echo 000)
[ "$s" = "200" ] && { echo "guide healthy"; exit 0; }
sleep 5
done
echo "::error::guide did not report healthy after deploy"; exit 1
# Posts a ✅/🔴 card to #hiveops-dev-deploy on every run (deploy result). Runs even on
# failure so a broken build/deploy/smoke is announced, not silent. SLACK_WEBHOOK_URL is an
# org secret; if unset the step no-ops so forks/dry-runs don't error.
- name: Notify Slack (#hiveops-dev-deploy)
if: always()
continue-on-error: true # a notification must NEVER fail the deploy
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
JOB_STATUS: ${{ job.status }}
ACTOR: ${{ github.actor }}
REF_NAME: ${{ github.ref_name }}
SHA: ${{ github.sha }}
RUN_NUMBER: ${{ github.run_number }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
COMMIT_MSG: ${{ github.event.head_commit.message }}
run: |
[ -z "$SLACK_WEBHOOK_URL" ] && { echo "no SLACK_WEBHOOK_URL secret — skipping"; exit 0; }
SHORT="${SHA:0:8}"
FIRST="${COMMIT_MSG%%$'\n'*}" # first line via param-expansion (no pipe)
SUBJECT="$(printf '%s' "$FIRST" | tr -d '"\\' | cut -c1-100)"
if [ "$JOB_STATUS" = "success" ]; then
COLOR="#2eb67d"; TITLE=":white_check_mark: guide → bcos.dev deployed"
else
COLOR="#e01e5a"; TITLE=":red_circle: guide → bcos.dev deploy FAILED ($JOB_STATUS)"
fi
PAYLOAD=$(printf '{"attachments":[{"color":"%s","blocks":[{"type":"section","text":{"type":"mrkdwn","text":"*%s*"}},{"type":"section","fields":[{"type":"mrkdwn","text":"*Commit*\\n`%s` %s"},{"type":"mrkdwn","text":"*Branch*\\n%s"},{"type":"mrkdwn","text":"*By*\\n%s"},{"type":"mrkdwn","text":"*Run*\\n#%s"}]},{"type":"actions","elements":[{"type":"button","text":{"type":"plain_text","text":"View run"},"url":"%s"}]}]}]}' \
"$COLOR" "$TITLE" "$SHORT" "$SUBJECT" "$REF_NAME" "$ACTOR" "$RUN_NUMBER" "$RUN_URL")
# Non-fatal: capture the HTTP code, never let curl's exit fail the step.
code=$(curl -s -o /dev/null -w '%{http_code}' --max-time 15 -X POST -H 'Content-type: application/json' --data "$PAYLOAD" "$SLACK_WEBHOOK_URL" || echo "curl-error")
echo "slack notify HTTP: $code (200 = card posted; anything else = runner could not reach Slack)"