feat(water-log): run Smartsheet sync via Gitea Actions cron + persist secrets on deploy
Deploy to route.crispygoat.com / deploy (push) Successful in 4m20s
Deploy to route.crispygoat.com / deploy (push) Successful in 4m20s
- New .gitea/workflows/smartsheet-cron.yml: hits POST /api/water-log/smartsheet-sync every 15min with SMARTSHEET_CRON_SECRET bearer. Replaces the no-op vercel.json cron entry (ignored on self-hosted Gitea). - deploy.yml now writes SMARTSHEET_TOKEN_ENC_KEY and SMARTSHEET_CRON_SECRET to the runtime .env on every deploy so we don't silently lose them. - Dropped the unused cron entry from vercel.json.
This commit is contained in:
@@ -68,6 +68,8 @@ jobs:
|
||||
MINIO_BUCKET_WATER_LOGS: ${{ secrets.MINIO_BUCKET_WATER_LOGS }}
|
||||
MINIMAX_API_KEY: ${{ secrets.MINIMAX_API_KEY }}
|
||||
MINIMAX_BASE_URL: ${{ secrets.MINIMAX_BASE_URL }}
|
||||
SMARTSHEET_TOKEN_ENC_KEY: ${{ secrets.SMARTSHEET_TOKEN_ENC_KEY }}
|
||||
SMARTSHEET_CRON_SECRET: ${{ secrets.SMARTSHEET_CRON_SECRET }}
|
||||
run: npm run build
|
||||
|
||||
- name: Deploy
|
||||
@@ -108,6 +110,8 @@ jobs:
|
||||
MINIMAX_API_KEY: ${{ secrets.MINIMAX_API_KEY }}
|
||||
MINIMAX_BASE_URL: ${{ secrets.MINIMAX_BASE_URL }}
|
||||
CRON_SECRET: ${{ secrets.CRON_SECRET }}
|
||||
SMARTSHEET_TOKEN_ENC_KEY: ${{ secrets.SMARTSHEET_TOKEN_ENC_KEY }}
|
||||
SMARTSHEET_CRON_SECRET: ${{ secrets.SMARTSHEET_CRON_SECRET }}
|
||||
SERVER_SSH_KEY: ${{ secrets.SERVER_SSH_KEY }}
|
||||
run: |
|
||||
set -e
|
||||
@@ -173,6 +177,8 @@ jobs:
|
||||
printf 'MINIMAX_API_KEY=%s\n' "$MINIMAX_API_KEY"
|
||||
printf 'MINIMAX_BASE_URL=%s\n' "$MINIMAX_BASE_URL"
|
||||
printf 'CRON_SECRET=%s\n' "$CRON_SECRET"
|
||||
printf 'SMARTSHEET_TOKEN_ENC_KEY=%s\n' "$SMARTSHEET_TOKEN_ENC_KEY"
|
||||
printf 'SMARTSHEET_CRON_SECRET=%s\n' "$SMARTSHEET_CRON_SECRET"
|
||||
} > "$ENV_FILE"
|
||||
|
||||
# Upload env file and sync build output
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
name: Smartsheet sync cron
|
||||
|
||||
# Replaces the `vercel.json` cron entry (ignored on self-hosted Gitea).
|
||||
# Drains the Smartsheet sync queue every 15 minutes via the running
|
||||
# Next.js app's POST /api/water-log/smartsheet-sync endpoint.
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Every 15 minutes. Gitea Actions uses standard 5-field cron syntax;
|
||||
# `0,15,30,45 * * * *` is the explicit form to avoid `*/15`
|
||||
# parser quirks across older Gitea versions.
|
||||
- cron: "0,15,30,45 * * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
drain-sync-queue:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Hit /api/water-log/smartsheet-sync
|
||||
env:
|
||||
SMARTSHEET_CRON_SECRET: ${{ secrets.SMARTSHEET_CRON_SECRET }}
|
||||
SITE_URL: ${{ secrets.NEXT_PUBLIC_SITE_URL }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [ -z "$SMARTSHEET_CRON_SECRET" ]; then
|
||||
echo "SMARTSHEET_CRON_SECRET secret not set — skipping."
|
||||
exit 0
|
||||
fi
|
||||
if [ -z "$SITE_URL" ]; then
|
||||
echo "NEXT_PUBLIC_SITE_URL secret not set — skipping."
|
||||
exit 0
|
||||
fi
|
||||
echo "POST $SITE_URL/api/water-log/smartsheet-sync"
|
||||
curl -fsS --max-time 60 -X POST \
|
||||
-H "Authorization: Bearer $SMARTSHEET_CRON_SECRET" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "User-Agent: gitea-smartsheet-cron/1" \
|
||||
"${SITE_URL%/}/api/water-log/smartsheet-sync" \
|
||||
--data '{}' \
|
||||
-w "\n[http %{http_code} in %{time_total}s]\n"
|
||||
@@ -747,3 +747,19 @@ c.commit()
|
||||
Gitea is on **SQLite** here (`/home/git/data/gitea.db`), not the
|
||||
`HOST = 127.0.0.1:3306` listed in app.ini (that's stale config from
|
||||
when the DB was MySQL).
|
||||
|
||||
## 2026-07: Smartsheet cron now runs via Gitea Actions, not vercel.json
|
||||
|
||||
The `*/15` cron entry in `vercel.json` is silently ignored because
|
||||
the host is self-hosted Gitea, not Vercel. Replaced with
|
||||
`.gitea/workflows/smartsheet-cron.yml`, schedule `0,15,30,45 * * * *`.
|
||||
|
||||
`deploy.yml` now writes `SMARTSHEET_TOKEN_ENC_KEY` and
|
||||
`SMARTSHEET_CRON_SECRET` into the runtime `.env`. Without this,
|
||||
any future deploy would silently drop these secrets and break
|
||||
runtime sync (encrypted token storage, cron auth).
|
||||
|
||||
If the cron ever returns 401, check `SMARTSHEET_CRON_SECRET`
|
||||
matches between Gitea repo secrets and the live `.env`. The
|
||||
runtime route at `POST /api/water-log/smartsheet-sync` falls
|
||||
back to `CRON_SECRET` if `SMARTSHEET_CRON_SECRET` is unset.
|
||||
|
||||
@@ -32,10 +32,6 @@
|
||||
{
|
||||
"path": "/api/cron/send-scheduled",
|
||||
"schedule": "0 9 * * *"
|
||||
},
|
||||
{
|
||||
"path": "/api/water-log/smartsheet-sync",
|
||||
"schedule": "*/15 * * * *"
|
||||
}
|
||||
],
|
||||
"headers": [
|
||||
|
||||
Reference in New Issue
Block a user