git-lfs's pre-push hook rejects pushes that reference LFS objects the local checkout doesn't have. Since we skipped smudge on checkout (GIT_LFS_SKIP_SMUDGE=1), no LFS content is local. But we're only pushing branch pointers — no new LFS bytes to upload. Tell lfs to allow the incomplete push via 'git config lfs.allowincompletepush true', per the hint the hook itself prints.
116 lines
5 KiB
YAML
116 lines
5 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"
|
|
# git-lfs pre-push hook refuses incomplete pushes — which triggers
|
|
# here because we skipped LFS smudge on checkout, so local LFS
|
|
# objects are absent. We're only pushing branch pointers (no new
|
|
# LFS content), so allow incomplete.
|
|
git config lfs.allowincompletepush true
|
|
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"
|