Generic host/repo/branch-aware CD on adnanh/webhook
Replaces the per-project deploy scripts and self-contained webhook receivers with one manifest-driven implementation that lives outside the application repositories and can be updated independently of them. First targets: domaindingo test and prod on s5.
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
# Cloudflare R2 CI Setup
|
||||
|
||||
Upload a build artifact (e.g. a status JSON) to an R2 bucket from CI, using
|
||||
`awscli` against R2's S3-compatible API.
|
||||
|
||||
## Cloudflare side
|
||||
|
||||
Create a bucket and a write-capable API token/key pair; note the account ID.
|
||||
|
||||
## CI config
|
||||
|
||||
Variables: `R2_BUCKET_NAME`, `R2_ACCOUNT_ID`.
|
||||
Secrets: `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`.
|
||||
|
||||
The keys must be passed as `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` —
|
||||
`awscli` reads those names. Also required: `AWS_DEFAULT_REGION=auto` and
|
||||
endpoint `https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com`.
|
||||
|
||||
## Job
|
||||
|
||||
```yaml
|
||||
publish_status:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-python@v6
|
||||
with: { python-version: "3.12" }
|
||||
- run: pip install awscli
|
||||
- name: Publish to R2
|
||||
env:
|
||||
R2_BUCKET_NAME: ${{ vars.R2_BUCKET_NAME }}
|
||||
R2_ACCOUNT_ID: ${{ vars.R2_ACCOUNT_ID }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||
run: |
|
||||
set -eu
|
||||
# If publish is optional, skip on missing config; use exit 1 if mandatory.
|
||||
[ -n "${R2_BUCKET_NAME:-}" ] && [ -n "${R2_ACCOUNT_ID:-}" ] \
|
||||
&& [ -n "${AWS_ACCESS_KEY_ID:-}" ] && [ -n "${AWS_SECRET_ACCESS_KEY:-}" ] \
|
||||
|| { echo "Skipping: R2 config not set."; exit 0; }
|
||||
f="$(mktemp -d)/project-name.json"
|
||||
cat > "$f" <<EOF
|
||||
{"generated_at":"$(date -u +"%Y-%m-%d %H:%M UTC")","build":{"state":"passing"}}
|
||||
EOF
|
||||
AWS_DEFAULT_REGION=auto aws s3api put-object \
|
||||
--bucket "$R2_BUCKET_NAME" --key "project-name.json" --body "$f" \
|
||||
--content-type application/json \
|
||||
--endpoint-url "https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com"
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Keep object keys explicit and stable (`project-name.json`,
|
||||
`status/project-name.json`). For dashboards, don't put commit SHAs in the
|
||||
primary key without also keeping a stable "latest" pointer.
|
||||
- Common failures: wrong account ID (bad endpoint), wrong bucket (auth ok but
|
||||
write fails), missing AWS env vars (no auth), missing `AWS_DEFAULT_REGION=auto`
|
||||
(inconsistent behaviour), using the standard AWS S3 endpoint instead of R2.
|
||||
@@ -0,0 +1,48 @@
|
||||
# ntfy CI Notification Setup
|
||||
|
||||
Send an `ntfy` message on workflow success and another on failure, for push
|
||||
events only. Needs `curl` in the runner and the ntfy server reachable from CI.
|
||||
|
||||
- Base URL via workflow env: `NTFY_BASE_URL: https://ntfy.fisher.hu`
|
||||
- Topic = repo name with `/` → `-`: `topic="${GITHUB_REPOSITORY//\//-}"`
|
||||
(e.g. `webdev/domaindingo` → `webdev-domaindingo`)
|
||||
|
||||
```yaml
|
||||
env:
|
||||
NTFY_BASE_URL: https://ntfy.fisher.hu
|
||||
|
||||
jobs:
|
||||
notify_ok:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build, publish_project_status] # replace with your pipeline jobs
|
||||
if: ${{ always() && github.event_name == 'push' && needs.build.result == 'success' && needs.publish_project_status.result == 'success' }}
|
||||
steps:
|
||||
- name: Notify ntfy (success)
|
||||
env: { COMMIT_MESSAGE: "${{ github.event.head_commit.message }}" }
|
||||
run: |
|
||||
topic="${GITHUB_REPOSITORY//\//-}"
|
||||
curl -fsS -d "✅ Repo: ${GITHUB_REPOSITORY} | Branch: ${GITHUB_REF_NAME} | Message: ${COMMIT_MESSAGE}" \
|
||||
"${NTFY_BASE_URL}/${topic}"
|
||||
|
||||
notify_failure:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build, publish_project_status]
|
||||
if: ${{ always() && github.event_name == 'push' && (needs.build.result != 'success' || needs.publish_project_status.result != 'success') }}
|
||||
steps:
|
||||
- name: Notify ntfy (failure)
|
||||
env: { COMMIT_MESSAGE: "${{ github.event.head_commit.message }}" }
|
||||
run: |
|
||||
topic="${GITHUB_REPOSITORY//\//-}"
|
||||
curl -fsS -d "❌ Repo: ${GITHUB_REPOSITORY} | Branch: ${GITHUB_REF_NAME} | Message: ${COMMIT_MESSAGE}" \
|
||||
"${NTFY_BASE_URL}/${topic}"
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- `needs:` must list the jobs that define "done"; the `if:` expressions decide
|
||||
success vs. failure. Keep `always()` so the failure job still runs when an
|
||||
upstream job fails.
|
||||
- Limit to `push`: `github.event.head_commit.message` is absent on other events.
|
||||
- `curl -fsS` fails the step on HTTP errors while still printing diagnostics.
|
||||
- Auth: if the server needs a token, store it as a secret and add
|
||||
`-H "Authorization: Bearer ${NTFY_TOKEN}"` to the curl call.
|
||||
Reference in New Issue
Block a user