Run 90 hit two problems in sequence:
1. Built-in $GITEA_TOKEN is read-only by default in Gitea Actions, so
'git push origin main' 404'd ('failed to push some refs'). Swapped
to a new GIT_PUSH_TOKEN repo secret (admin-scoped PAT) which the
checkout action uses when wiring the authenticated remote.
2. None of our bot accounts are currently in the Infra Matrix room, so
the notification POST would 403 and fail the whole run. Made that
step continue-on-error — the sync is the critical path; a missed
ping is recoverable (check Actions UI, invite a bot later, etc).
111 lines
4.7 KiB
YAML
111 lines
4.7 KiB
YAML
name: Upstream sync
|
|
|
|
# Daily check against the upstream mirror. Fast-forwards `main` to
|
|
# `upstream/develop` when upstream has advanced, then pings the Infra
|
|
# Matrix room so we know the wallet branch is due for a rebase.
|
|
#
|
|
# See SYNC.md on the wallet branch for the full topology + procedure
|
|
# this job implements.
|
|
|
|
on:
|
|
schedule:
|
|
# 12:00 UTC daily — quiet time for all our time zones, avoids the
|
|
# morning-meeting window where an unexpected Matrix ping is noise.
|
|
- cron: '0 12 * * *'
|
|
workflow_dispatch: # manual trigger from the Actions UI too
|
|
|
|
jobs:
|
|
sync-main:
|
|
runs-on: ubuntu-latest
|
|
env:
|
|
# The repo's .gitattributes (inherited from upstream) routes the
|
|
# screenshots/ tree through git-lfs. Gitea's LFS store doesn't hold
|
|
# those blobs, so on checkout the smudge filter tries to 404-download
|
|
# them and wedges git state for subsequent fetches. We don't need
|
|
# the image bytes here — leave LFS pointers as-is.
|
|
GIT_LFS_SKIP_SMUDGE: '1'
|
|
|
|
steps:
|
|
- name: Checkout main
|
|
uses: actions/checkout@v4
|
|
with:
|
|
ref: main
|
|
fetch-depth: 0
|
|
lfs: false
|
|
# Gitea's built-in GITEA_TOKEN is read-only by default.
|
|
# GIT_PUSH_TOKEN is a repo secret with a write-scoped PAT, so
|
|
# the subsequent `git push origin main` actually lands.
|
|
token: ${{ secrets.GIT_PUSH_TOKEN }}
|
|
|
|
- name: Fetch upstream + wallet
|
|
run: |
|
|
set -euo pipefail
|
|
# Fetch directly from GitHub. We also have a Gitea pull-mirror
|
|
# at Sulkta-Coop/element-x-upstream that tracks this same repo,
|
|
# but sourcing from GitHub keeps the workflow independent of
|
|
# the mirror's health — one less moving part to diagnose.
|
|
git remote add upstream https://github.com/element-hq/element-x-android.git
|
|
git fetch --depth=500 upstream develop
|
|
git fetch origin wallet:refs/remotes/origin/wallet
|
|
|
|
- name: Fast-forward main
|
|
id: ff
|
|
run: |
|
|
set -euo pipefail
|
|
git config user.name "sulkta-bot"
|
|
git config user.email "bot@sulkta.com"
|
|
OLD=$(git rev-parse --short HEAD)
|
|
echo "main was at $OLD"
|
|
if git merge --ff-only upstream/develop; then
|
|
NEW=$(git rev-parse --short HEAD)
|
|
if [ "$OLD" = "$NEW" ]; then
|
|
echo "main already up to date with upstream/develop"
|
|
echo "advanced=false" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "main advanced: $OLD -> $NEW"
|
|
git push origin main
|
|
echo "advanced=true" >> "$GITHUB_OUTPUT"
|
|
echo "old=$OLD" >> "$GITHUB_OUTPUT"
|
|
echo "new=$NEW" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
else
|
|
echo "::warning::main could not fast-forward to upstream/develop — someone committed to main directly?"
|
|
echo "advanced=false" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Measure wallet drift
|
|
if: steps.ff.outputs.advanced == 'true'
|
|
id: drift
|
|
run: |
|
|
set -euo pipefail
|
|
MB=$(git merge-base refs/remotes/origin/wallet main)
|
|
BEHIND=$(git rev-list --count "$MB..main")
|
|
NEW_ADDED=$(git rev-list --count "$MB..upstream/develop")
|
|
echo "behind=$BEHIND" >> "$GITHUB_OUTPUT"
|
|
echo "new_added=$NEW_ADDED" >> "$GITHUB_OUTPUT"
|
|
echo "wallet is $BEHIND commits behind main now; $NEW_ADDED new upstream commits this run"
|
|
|
|
- name: Matrix notification (Infra room)
|
|
# Best-effort — if the target bot isn't in the room or Matrix is
|
|
# flapping, don't fail the whole run. The advance + push is the
|
|
# critical path; notify is a convenience ping.
|
|
if: steps.ff.outputs.advanced == 'true'
|
|
continue-on-error: true
|
|
env:
|
|
MATRIX_TOKEN: ${{ secrets.MATRIX_HOUSE_BOT_TOKEN }}
|
|
run: |
|
|
set -euo pipefail
|
|
TXN=$(date +%s%N)
|
|
ROOM='!rvxiUrWpgvMTAwzjGm:sulkta.com' # Infra
|
|
BODY="element-x upstream advanced · main ${{ steps.ff.outputs.old }} → ${{ steps.ff.outputs.new }} (${{ steps.drift.outputs.new_added }} commits). wallet is ${{ steps.drift.outputs.behind }} commits behind — rebase before next build."
|
|
|
|
# jq keeps the body properly JSON-escaped; safer than shell interp
|
|
# shellcheck disable=SC2086
|
|
PAYLOAD=$(printf '%s' "$BODY" | jq -Rs '{msgtype: "m.text", body: .}')
|
|
|
|
curl --fail -s -X PUT \
|
|
-H "Authorization: Bearer $MATRIX_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
"https://chat.sulkta.com/_matrix/client/v3/rooms/${ROOM}/send/m.room.message/${TXN}" \
|
|
-d "$PAYLOAD"
|
|
echo "notified"
|