Skip to content

Commit d7ae7f7

Browse files
committed
macOS: apply recovered 20250912 cumulative checkpoint
1 parent b442ad9 commit d7ae7f7

32 files changed

Lines changed: 10535 additions & 1391 deletions

.gitea/workflows/auto-open-prs.yml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Auto-open a pull request into the default branch when a non-default branch is pushed.
2+
#
3+
# Requirements:
4+
# - Repository secret GITEA_TOKEN with API scope that can open PRs on this fork.
5+
# - Optional repository variable DEFAULT_BRANCH to override the default branch name (defaults to "main").
6+
7+
name: Auto Open PRs
8+
9+
on:
10+
push:
11+
branches-ignore:
12+
- main
13+
- master
14+
workflow_dispatch: {}
15+
16+
jobs:
17+
open-pr:
18+
runs-on: docker
19+
env:
20+
DEFAULT_BRANCH: ${{ vars.DEFAULT_BRANCH || 'main' }}
21+
steps:
22+
- name: Derive server, repo, and branch
23+
id: drv
24+
shell: bash
25+
run: |
26+
set -euo pipefail
27+
SERVER_URL="${GITHUB_SERVER_URL:-${GITEA_SERVER_URL:-}}"
28+
REPO_PATH="${GITHUB_REPOSITORY:-${GITEA_REPOSITORY:-}}"
29+
# Branch name from ref variables
30+
BR="${GITHUB_REF_NAME:-${GITEA_REF_NAME:-}}"
31+
if [ -z "$BR" ]; then
32+
REF="${GITHUB_REF:-${GITEA_REF:-}}"
33+
BR="${REF##refs/heads/}"
34+
fi
35+
if [ -z "$SERVER_URL" ] || [ -z "$REPO_PATH" ] || [ -z "$BR" ]; then
36+
echo "Missing SERVER_URL, REPO_PATH or branch name from env." >&2
37+
exit 1
38+
fi
39+
echo "SERVER_URL=$SERVER_URL" >> "$GITHUB_OUTPUT"
40+
echo "REPO_PATH=$REPO_PATH" >> "$GITHUB_OUTPUT"
41+
echo "PUSH_BRANCH=$BR" >> "$GITHUB_OUTPUT"
42+
echo "Default branch: $DEFAULT_BRANCH; Push branch: $BR" >&2
43+
44+
- name: Skip default branch
45+
if: ${{ steps.drv.outputs.PUSH_BRANCH == env.DEFAULT_BRANCH }}
46+
run: echo "Push to default branch; nothing to do." >&2
47+
48+
- name: Ensure PR exists or create
49+
if: ${{ steps.drv.outputs.PUSH_BRANCH != env.DEFAULT_BRANCH }}
50+
shell: bash
51+
env:
52+
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
53+
run: |
54+
set -euo pipefail
55+
API_BASE="${{ steps.drv.outputs.SERVER_URL }}/api/v1"
56+
REPO="${{ steps.drv.outputs.REPO_PATH }}"
57+
BRANCH="${{ steps.drv.outputs.PUSH_BRANCH }}"
58+
# Check existing open PRs for this head branch
59+
PRS=$(curl -sfSL -H "Authorization: token ${GITEA_TOKEN}" "${API_BASE}/repos/${REPO}/pulls?state=open")
60+
# Try to detect if a PR for this head exists (head_branch may be present; fallback to scanning title/body for branch string)
61+
if echo "$PRS" | grep -q "\"head_branch\"\s*:\s*\"$BRANCH\""; then
62+
echo "PR already open for $BRANCH; skipping." >&2
63+
exit 0
64+
fi
65+
TITLE="Auto-PR: $BRANCH -> $DEFAULT_BRANCH"
66+
BODY="Automatically opened pull request for branch $BRANCH into $DEFAULT_BRANCH."
67+
JSON_PAYLOAD=$(printf '{"title":"%s","body":"%s","head":"%s","base":"%s"}' \
68+
"$TITLE" "$BODY" "$BRANCH" "$DEFAULT_BRANCH")
69+
curl -sfSL -X POST \
70+
-H "Content-Type: application/json" \
71+
-H "Authorization: token ${GITEA_TOKEN}" \
72+
"${API_BASE}/repos/${REPO}/pulls" \
73+
-d "$JSON_PAYLOAD"
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# Auto-rebase open PR branches against the default branch (main by default).
2+
#
3+
# Requirements:
4+
# - Repository secret GITEA_TOKEN with API scope that can read PRs and push to branches in this fork.
5+
# - Optional repository variable DEFAULT_BRANCH to override the default branch name (defaults to "main").
6+
#
7+
# Behavior:
8+
# - Lists open PRs in this repo. For PRs whose head branch is in this repo,
9+
# rebases the branch onto the default branch and force-pushes with lease.
10+
# - On rebase conflict, aborts and posts a comment on the PR asking for manual resolution.
11+
12+
name: Auto Rebase PRs
13+
14+
on:
15+
schedule:
16+
- cron: "*/30 * * * *" # every 30 minutes
17+
workflow_dispatch: {}
18+
19+
jobs:
20+
rebase:
21+
runs-on: docker
22+
env:
23+
DEFAULT_BRANCH: ${{ vars.DEFAULT_BRANCH || 'main' }}
24+
steps:
25+
- name: Derive server and repo
26+
id: drv
27+
shell: bash
28+
run: |
29+
set -euo pipefail
30+
SERVER_URL="${GITHUB_SERVER_URL:-${GITEA_SERVER_URL:-}}"
31+
REPO_PATH="${GITHUB_REPOSITORY:-${GITEA_REPOSITORY:-}}"
32+
if [ -z "$SERVER_URL" ] || [ -z "$REPO_PATH" ]; then
33+
echo "Missing SERVER_URL or REPO_PATH from env (GITHUB_* or GITEA_*)" >&2
34+
exit 1
35+
fi
36+
echo "SERVER_URL=$SERVER_URL" >> "$GITHUB_OUTPUT"
37+
echo "REPO_PATH=$REPO_PATH" >> "$GITHUB_OUTPUT"
38+
39+
- name: Prepare repository clone
40+
shell: bash
41+
run: |
42+
set -euo pipefail
43+
git init work
44+
cd work
45+
git config user.name "gitea-actions"
46+
git config user.email "actions@localhost"
47+
ORIGIN_URL="${{ steps.drv.outputs.SERVER_URL }}/${{ steps.drv.outputs.REPO_PATH }}.git"
48+
git remote add origin "$ORIGIN_URL"
49+
git fetch --prune origin
50+
git checkout -B "$DEFAULT_BRANCH" "origin/$DEFAULT_BRANCH" || git checkout -B "$DEFAULT_BRANCH"
51+
52+
- name: List open PRs
53+
id: list
54+
shell: bash
55+
env:
56+
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
57+
run: |
58+
set -euo pipefail
59+
API_BASE="${{ steps.drv.outputs.SERVER_URL }}/api/v1"
60+
REPO="${{ steps.drv.outputs.REPO_PATH }}"
61+
AUTH=(-H "Authorization: token ${GITEA_TOKEN}")
62+
curl -sfSL "${API_BASE}/repos/${REPO}/pulls?state=open" "${AUTH[@]}" > prs.json
63+
echo "Pulled PR list:" >&2; wc -c prs.json >&2 || true
64+
# Extract: pr_number, head_branch, base_branch, head_repo_full_name
65+
python3 - << 'PY' < prs.json > pr_list.txt
66+
import sys, json
67+
data=json.load(sys.stdin)
68+
def repo_name(r):
69+
if not r:
70+
return ''
71+
# Try common fields
72+
return r.get('full_name') or (
73+
(r.get('owner',{}).get('login','') + '/' + r.get('name','')).strip('/')
74+
)
75+
for pr in data:
76+
num = pr.get('number') or pr.get('index')
77+
head = pr.get('head') if isinstance(pr.get('head'), str) else pr.get('head_branch')
78+
base = pr.get('base') if isinstance(pr.get('base'), str) else pr.get('base_branch')
79+
head_repo = repo_name(pr.get('head_repo') or pr.get('head_repo'))
80+
print(f"{num}\t{head or ''}\t{base or ''}\t{head_repo}")
81+
PY
82+
echo "PR list:" >&2; cat pr_list.txt >&2 || true
83+
84+
- name: Rebase each PR branch
85+
shell: bash
86+
env:
87+
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
88+
run: |
89+
set -euo pipefail
90+
cd work
91+
API_BASE="${{ steps.drv.outputs.SERVER_URL }}/api/v1"
92+
REPO="${{ steps.drv.outputs.REPO_PATH }}"
93+
while IFS=$'\t' read -r PR_NUM HEAD_BRANCH BASE_BRANCH HEAD_REPO; do
94+
[ -n "$PR_NUM" ] || continue
95+
# Skip if head branch is empty
96+
if [ -z "$HEAD_BRANCH" ]; then
97+
echo "PR #$PR_NUM: no head branch reported; skipping" >&2
98+
continue
99+
fi
100+
# Only rebase branches that live in this repo
101+
if [ -n "$HEAD_REPO" ] && [ "$HEAD_REPO" != "${REPO}" ]; then
102+
echo "PR #$PR_NUM: head repo is external ($HEAD_REPO); skipping" >&2
103+
continue
104+
fi
105+
echo "Rebasing PR #$PR_NUM branch '$HEAD_BRANCH' onto '$DEFAULT_BRANCH'" >&2
106+
git fetch origin "$DEFAULT_BRANCH" "$HEAD_BRANCH" || true
107+
if ! git show-ref --verify --quiet "refs/remotes/origin/$HEAD_BRANCH"; then
108+
echo "PR #$PR_NUM: origin/$HEAD_BRANCH not found; skipping" >&2
109+
continue
110+
fi
111+
git checkout -B "$HEAD_BRANCH" "origin/$HEAD_BRANCH"
112+
set +e
113+
git rebase "origin/$DEFAULT_BRANCH"
114+
REBASE_STATUS=$?
115+
set -e
116+
if [ $REBASE_STATUS -ne 0 ]; then
117+
echo "PR #$PR_NUM: rebase conflict; aborting and commenting" >&2
118+
git rebase --abort || true
119+
# Post a comment
120+
if [ -n "$GITEA_TOKEN" ]; then
121+
COMMENT_PAYLOAD=$(printf '{"body":"Auto-rebase failed due to conflicts. Please rebase onto %s and resolve conflicts."}' "$DEFAULT_BRANCH")
122+
curl -sfSL -X POST \
123+
-H "Content-Type: application/json" \
124+
-H "Authorization: token ${GITEA_TOKEN}" \
125+
"${API_BASE}/repos/${REPO}/issues/${PR_NUM}/comments" \
126+
-d "$COMMENT_PAYLOAD" || true
127+
# Ensure a 'needs-rebase' label exists
128+
LABELS_JSON=$(curl -sfSL -H "Authorization: token ${GITEA_TOKEN}" "${API_BASE}/repos/${REPO}/labels" || echo '[]')
129+
LABEL_EXISTS=$(echo "$LABELS_JSON" | grep -i '"name"\s*:\s*"needs-rebase"' || true)
130+
if [ -z "$LABEL_EXISTS" ]; then
131+
curl -sfSL -X POST \
132+
-H "Content-Type: application/json" \
133+
-H "Authorization: token ${GITEA_TOKEN}" \
134+
"${API_BASE}/repos/${REPO}/labels" \
135+
-d '{"name":"needs-rebase","color":"#b60205"}' || true
136+
fi
137+
# Add label to the PR
138+
curl -sfSL -X POST \
139+
-H "Content-Type: application/json" \
140+
-H "Authorization: token ${GITEA_TOKEN}" \
141+
"${API_BASE}/repos/${REPO}/issues/${PR_NUM}/labels" \
142+
-d '["needs-rebase"]' || true
143+
fi
144+
# Do not push in conflict case
145+
continue
146+
fi
147+
echo "PR #$PR_NUM: rebase succeeded; pushing with lease" >&2
148+
git push --force-with-lease origin "$HEAD_BRANCH"
149+
done < ../pr_list.txt

.gitea/workflows/sync-upstream.yml

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# Sync upstream main from the mirror into this fork, and open a PR when a fast-forward is not possible.
2+
#
3+
# Requirements (set in your fork repository settings):
4+
# - Repository secret GITEA_TOKEN with API scope that can push and open PRs on this fork.
5+
# - Repository secret UPSTREAM_REPO set to the path of the upstream mirror inside this Gitea instance,
6+
# for example: "org/zed-mirror" (without .git).
7+
# - Optional repository variable DEFAULT_BRANCH to override the default branch name (defaults to "main").
8+
#
9+
# This workflow assumes the mirror repository (UPSTREAM_REPO) is already auto-synced from the real upstream.
10+
11+
name: Sync Upstream
12+
13+
on:
14+
schedule:
15+
- cron: "*/30 * * * *" # every 30 minutes
16+
workflow_dispatch: {}
17+
18+
jobs:
19+
sync-upstream:
20+
runs-on: docker
21+
env:
22+
DEFAULT_BRANCH: ${{ vars.DEFAULT_BRANCH || 'main' }}
23+
steps:
24+
- name: Derive server and repo
25+
id: drv
26+
shell: bash
27+
run: |
28+
set -euo pipefail
29+
# Prefer GitHub-compatible vars provided by Gitea Actions, fallback to Gitea-specific ones
30+
SERVER_URL="${GITHUB_SERVER_URL:-${GITEA_SERVER_URL:-}}"
31+
REPO_PATH="${GITHUB_REPOSITORY:-${GITEA_REPOSITORY:-}}"
32+
if [ -z "$SERVER_URL" ] || [ -z "$REPO_PATH" ]; then
33+
echo "Missing SERVER_URL or REPO_PATH from env (GITHUB_* or GITEA_*)" >&2
34+
exit 1
35+
fi
36+
echo "SERVER_URL=$SERVER_URL" >> "$GITHUB_OUTPUT"
37+
echo "REPO_PATH=$REPO_PATH" >> "$GITHUB_OUTPUT"
38+
39+
- name: Prepare repository
40+
shell: bash
41+
run: |
42+
set -euo pipefail
43+
git init sync-work
44+
cd sync-work
45+
git config user.name "gitea-actions"
46+
git config user.email "actions@localhost"
47+
ORIGIN_URL="${{ steps.drv.outputs.SERVER_URL }}/${{ steps.drv.outputs.REPO_PATH }}.git"
48+
git remote add origin "$ORIGIN_URL"
49+
git fetch --prune origin
50+
git checkout -B "$DEFAULT_BRANCH" "origin/$DEFAULT_BRANCH" || git checkout -B "$DEFAULT_BRANCH"
51+
52+
- name: Add upstream and fetch
53+
shell: bash
54+
env:
55+
UPSTREAM_REPO: ${{ secrets.UPSTREAM_REPO }}
56+
run: |
57+
set -euo pipefail
58+
if [ -z "${UPSTREAM_REPO:-}" ]; then
59+
echo "Secret UPSTREAM_REPO not set (expected '<owner>/<repo>')" >&2
60+
exit 1
61+
fi
62+
cd sync-work
63+
UPSTREAM_URL="${{ steps.drv.outputs.SERVER_URL }}/$UPSTREAM_REPO.git"
64+
if git remote get-url upstream >/dev/null 2>&1; then
65+
git remote set-url upstream "$UPSTREAM_URL"
66+
else
67+
git remote add upstream "$UPSTREAM_URL"
68+
fi
69+
git fetch --prune upstream
70+
71+
- name: Fast-forward or open PR
72+
shell: bash
73+
env:
74+
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
75+
run: |
76+
set -euo pipefail
77+
cd sync-work
78+
if git merge --ff-only "upstream/$DEFAULT_BRANCH"; then
79+
echo "Fast-forward merge succeeded. Pushing main." >&2
80+
git push origin "$DEFAULT_BRANCH"
81+
exit 0
82+
fi
83+
84+
# Create a sync branch with a regular merge (may leave conflicts to be resolved in PR)
85+
BR="sync/upstream-$(date -u +%Y%m%d%H%M%S)"
86+
git checkout -B "$BR"
87+
set +e
88+
git merge "upstream/$DEFAULT_BRANCH"
89+
MERGE_STATUS=$?
90+
set -e
91+
git push -u origin "$BR"
92+
93+
# Open a PR into main on this fork
94+
if [ -z "${GITEA_TOKEN:-}" ]; then
95+
echo "Secret GITEA_TOKEN not set; cannot open PR automatically." >&2
96+
exit 0
97+
fi
98+
API_BASE="${{ steps.drv.outputs.SERVER_URL }}/api/v1"
99+
REPO="${{ steps.drv.outputs.REPO_PATH }}"
100+
TITLE="Sync upstream into $DEFAULT_BRANCH ($BR)"
101+
BODY="Upstream: ${{ secrets.UPSTREAM_REPO }} | Branch: $BR | Merge status: $MERGE_STATUS"
102+
JSON_PAYLOAD=$(printf '{"title":"%s","body":"%s","head":"%s","base":"%s"}' \
103+
"$TITLE" "$BODY" "$BR" "$DEFAULT_BRANCH")
104+
curl -sfSL -X POST \
105+
-H "Content-Type: application/json" \
106+
-H "Authorization: token ${GITEA_TOKEN}" \
107+
"${API_BASE}/repos/${REPO}/pulls" \
108+
-d "$JSON_PAYLOAD"

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ members = [
108108
"crates/markdown_preview",
109109
"crates/media",
110110
"crates/menu",
111+
"crates/macos_appkit_bridge",
111112
"crates/migrator",
112113
"crates/mistral",
113114
"crates/miniprofiler_ui",

0 commit comments

Comments
 (0)