name: Deploy Better Life SG on: push: branches: [master] workflow_dispatch: concurrency: group: deploy-betterlifesg-${{ forgejo.ref }} cancel-in-progress: false jobs: deploy: runs-on: ubuntu-latest steps: - name: Configure SSH shell: bash env: VPS_SSH_KEY: ${{ secrets.VPS_SSH_KEY }} run: | set -euo pipefail install -d -m 700 ~/.ssh python3 - <<'PY' import os from pathlib import Path key = os.environ["VPS_SSH_KEY"] if "\\n" in key and "\n" not in key: key = key.replace("\\n", "\n") key = key.replace("\r\n", "\n").replace("\r", "\n").strip() + "\n" Path.home().joinpath(".ssh", "id_ed25519").write_text(key, encoding="utf-8") PY chmod 600 ~/.ssh/id_ed25519 ssh-keygen -y -f ~/.ssh/id_ed25519 >/dev/null ssh-keyscan -H 23.226.133.245 >> ~/.ssh/known_hosts - name: Deploy on VPS shell: bash run: | set -euo pipefail ssh root@23.226.133.245 "cd /opt/src/betterlifesg && bash scripts/deploy-betterlifesg.sh" notify: if: ${{ always() }} needs: [deploy] runs-on: ubuntu-latest steps: - name: Send ntfy notification shell: bash env: JOB_RESULTS: ${{ toJson(needs) }} NTFY_TOKEN: ${{ secrets.NTFY_TOKEN }} NTFY_TOPIC_URL: https://ntfy.bytesizeprotip.com/deploy RUN_URL: ${{ forgejo.server_url }}/${{ forgejo.repository }}/actions/runs/${{ forgejo.run_number }} run: | set -euo pipefail if [ -z "$NTFY_TOKEN" ]; then echo "NTFY_TOKEN secret not configured, skipping notification." exit 0 fi eval "$(python3 - <<'PY' import json import os import shlex needs = json.loads(os.environ["JOB_RESULTS"]) results = {name: str(data.get("result") or "unknown") for name, data in needs.items()} has_failure = any(result == "failure" for result in results.values()) has_cancelled = any(result == "cancelled" for result in results.values()) if has_failure: status = "failure" priority = "5" tags = "rotating_light,x" elif has_cancelled: status = "cancelled" priority = "4" tags = "warning" else: status = "success" priority = "2" tags = "white_check_mark" summary = ", ".join(f"{name}:{result}" for name, result in results.items()) or "no upstream jobs" message = "\n".join([ f"Repo: {os.environ['FORGEJO_REPOSITORY']}", f"Workflow: {os.environ['FORGEJO_WORKFLOW']}", f"Status: {status}", f"Ref: {os.environ.get('FORGEJO_REF_NAME', '')}", f"Actor: {os.environ.get('FORGEJO_ACTOR', '')}", f"Run: {os.environ['RUN_URL']}", f"Jobs: {summary}", ]) values = { "NTFY_TITLE": f"{os.environ['FORGEJO_WORKFLOW']} {status}", "NTFY_PRIORITY": priority, "NTFY_TAGS": tags, "NTFY_MESSAGE": message, } for key, value in values.items(): print(f"{key}={shlex.quote(value)}") PY )" curl --fail --show-error --silent \ -H "Authorization: Bearer $NTFY_TOKEN" \ -H "Title: $NTFY_TITLE" \ -H "Priority: $NTFY_PRIORITY" \ -H "Tags: $NTFY_TAGS" \ -H "Click: $RUN_URL" \ -d "$NTFY_MESSAGE" \ "$NTFY_TOPIC_URL"