diff --git a/.gitea/workflows/custom-release.yml b/.gitea/workflows/custom-release.yml index 40533aef5..ae5e346d6 100644 --- a/.gitea/workflows/custom-release.yml +++ b/.gitea/workflows/custom-release.yml @@ -12,6 +12,7 @@ on: - ".gitea/workflows/custom-release.yml" - "patches/**" - "scripts/update-custom-release.sh" + - "scripts/sync-upstream.sh" workflow_dispatch: inputs: upstream_tag: @@ -43,6 +44,11 @@ jobs: git config user.name "Gitea Actions" git config user.email "actions@git.felixfoertsch.de" + - name: Mirror upstream and rebuild patched main + run: ./scripts/sync-upstream.sh + env: + SYNC_REMOTE: origin + - name: Set up tea run: | go install code.gitea.io/tea@v0.14.1 diff --git a/.github/workflows/custom-release.yml b/.github/workflows/custom-release.yml index 87c0ff6df..a962291d5 100644 --- a/.github/workflows/custom-release.yml +++ b/.github/workflows/custom-release.yml @@ -11,6 +11,7 @@ on: - ".github/workflows/custom-release.yml" - "patches/**" - "scripts/update-custom-release.sh" + - "scripts/sync-upstream.sh" workflow_dispatch: inputs: upstream_tag: @@ -42,6 +43,11 @@ jobs: git config user.name "GitHub Actions" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + - name: Mirror upstream and rebuild patched main + run: ./scripts/sync-upstream.sh + env: + SYNC_REMOTE: origin + - name: Build patched Syncthing release run: | case "$(uname -m)" in diff --git a/patches/README.md b/patches/README.md index b42c27c96..d6930ea9b 100644 --- a/patches/README.md +++ b/patches/README.md @@ -34,6 +34,8 @@ CUSTOM_RELEASE_BUILDS="darwin/amd64/zip darwin/arm64/zip linux/amd64/tar linux/a The Gitea and GitHub workflows run the script on their respective CI hosts when the local patchset changes on `main`, on a schedule, and on manual dispatch. The repository's `upstream` branch stays a clean upstream mirror. +Before building, each host updates its own `upstream` branch from official +Syncthing `main` and rebuilds its patched `main` directly on that commit. The workflow detects the latest upstream Syncthing stable tag, exits if the matching custom tag already exists, pushes only the `-stignore.7` tag by default, and publishes release assets on the CI host running the workflow. diff --git a/scripts/sync-upstream.sh b/scripts/sync-upstream.sh new file mode 100755 index 000000000..d5693b5de --- /dev/null +++ b/scripts/sync-upstream.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +set -euo pipefail + +upstream_url="${SYNC_UPSTREAM_URL:-https://github.com/syncthing/syncthing.git}" +remote="${SYNC_REMOTE:-origin}" +upstream_branch="${SYNC_UPSTREAM_BRANCH:-upstream}" +main_branch="${SYNC_MAIN_BRANCH:-main}" +tmp="" + +die() { + printf 'error: %s\n' "$*" >&2 + exit 1 +} + +cleanup() { + [[ -z "$tmp" ]] || rm -rf "$tmp" +} + +main() { + [[ -z "$(git status --porcelain)" ]] || die "working tree has uncommitted changes" + + local current_main + local current_upstream + local new_upstream + current_main="$(git rev-parse "refs/heads/$main_branch")" + current_upstream="$(git rev-parse "refs/remotes/$remote/$upstream_branch")" + + git fetch "$upstream_url" "refs/heads/main:refs/remotes/official/main" + new_upstream="$(git rev-parse refs/remotes/official/main)" + if [[ "$new_upstream" == "$current_upstream" ]]; then + printf 'Upstream is already current at %s.\n' "$new_upstream" + return + fi + + tmp="$(mktemp -d)" + trap cleanup EXIT + mkdir -p "$tmp/.gitea/workflows" "$tmp/.github/workflows" "$tmp/patches" "$tmp/scripts/tests" + cp .gitea/workflows/custom-release.yml "$tmp/.gitea/workflows/" + cp .github/workflows/custom-release.yml "$tmp/.github/workflows/" + cp patches/*.patch patches/README.md "$tmp/patches/" + cp scripts/update-custom-release.sh scripts/sync-upstream.sh "$tmp/scripts/" + cp scripts/tests/test-custom-release-macos-runner.bats "$tmp/scripts/tests/" + + git branch -f "$upstream_branch" "$new_upstream" + git push --force-with-lease="$upstream_branch:$current_upstream" "$remote" "$upstream_branch" + + git checkout -B "$main_branch" "$new_upstream" + cp -R "$tmp/.gitea" "$tmp/.github" "$tmp/patches" "$tmp/scripts" . + git apply patches/sync-stignore.patch patches/webui-build-marker.patch + git add -A + git commit -m "sync upstream, apply stignore patch" + git push --force-with-lease="$main_branch:$current_main" "$remote" "$main_branch" +} + +main "$@" diff --git a/scripts/tests/test-custom-release-macos-runner.bats b/scripts/tests/test-custom-release-macos-runner.bats index b5d2a1463..1f9b8baf1 100644 --- a/scripts/tests/test-custom-release-macos-runner.bats +++ b/scripts/tests/test-custom-release-macos-runner.bats @@ -5,6 +5,19 @@ setup() { WORKFLOW="$REPO_ROOT/.gitea/workflows/custom-release.yml" GITHUB_WORKFLOW="$REPO_ROOT/.github/workflows/custom-release.yml" RELEASE_SCRIPT="$REPO_ROOT/scripts/update-custom-release.sh" + SYNC_SCRIPT="$REPO_ROOT/scripts/sync-upstream.sh" +} + +@test "both hosts mirror upstream before building their own release" { + run rg -n 'run: ./scripts/sync-upstream.sh' "$WORKFLOW" "$GITHUB_WORKFLOW" + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 2 ] + + run rg -n 'git push --force-with-lease=.*upstream|git push --force-with-lease=.*main' "$SYNC_SCRIPT" + [ "$status" -eq 0 ] + + run rg -n 'git apply patches/sync-stignore.patch patches/webui-build-marker.patch' "$SYNC_SCRIPT" + [ "$status" -eq 0 ] } @test "github custom release uses a github macos runner and github releases" {