Skip to content

Commit 7020e28

Browse files
author
NagyVikt
committed
new
1 parent f203238 commit 7020e28

7 files changed

Lines changed: 213 additions & 0 deletions

File tree

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Sync Frontend Mirror
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- frontend/**
9+
- scripts/sync-frontend-mirror.sh
10+
- .github/workflows/sync-frontend-mirror.yml
11+
workflow_dispatch:
12+
13+
permissions:
14+
contents: read
15+
16+
concurrency:
17+
group: sync-frontend-mirror
18+
cancel-in-progress: false
19+
20+
jobs:
21+
sync:
22+
runs-on: ubuntu-latest
23+
env:
24+
TARGET_REPO: ${{ vars.GUARDEX_FRONTEND_MIRROR_REPO || 'Webu-PRO/guardex-frontend' }}
25+
TARGET_BRANCH: ${{ vars.GUARDEX_FRONTEND_MIRROR_BRANCH || 'main' }}
26+
SOURCE_PREFIX: frontend
27+
SYNC_TOKEN: ${{ secrets.GUARDEX_FRONTEND_MIRROR_PAT }}
28+
steps:
29+
- name: Checkout
30+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
31+
with:
32+
fetch-depth: 0
33+
34+
- name: Sync frontend subtree to mirror repo
35+
run: bash scripts/sync-frontend-mirror.sh

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,34 @@ Then in your repo:
287287

288288
After that, the app reviews new and updated pull requests automatically.
289289

290+
## Frontend mirror sync (`Webu-PRO/guardex-frontend`)
291+
292+
This repo includes `.github/workflows/sync-frontend-mirror.yml`, which mirrors
293+
the `frontend/` subtree to a separate repository whenever `main` receives
294+
changes under `frontend/**`.
295+
296+
Default target:
297+
298+
- repo: `Webu-PRO/guardex-frontend`
299+
- branch: `main`
300+
301+
Required setup (in this repository):
302+
303+
1. `Settings -> Secrets and variables -> Actions`
304+
2. Add repository secret `GUARDEX_FRONTEND_MIRROR_PAT`
305+
- value must be a token with `contents:write` access to `Webu-PRO/guardex-frontend`
306+
307+
Optional overrides (Actions Variables):
308+
309+
- `GUARDEX_FRONTEND_MIRROR_REPO` (default `Webu-PRO/guardex-frontend`)
310+
- `GUARDEX_FRONTEND_MIRROR_BRANCH` (default `main`)
311+
312+
Manual run:
313+
314+
```sh
315+
gh workflow run sync-frontend-mirror.yml
316+
```
317+
290318
## Companion dependency: `codex-auth` account switcher
291319

292320
For multi-identity Codex workflows, GuardeX pairs with
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
schema: spec-driven
2+
created: 2026-04-20
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
## Why
2+
3+
- The user requested that updates to the `frontend/` app in this repository also update `https://github.com/Webu-PRO/guardex-frontend`.
4+
- The current workflow does not automatically publish frontend subtree updates to that external repository.
5+
6+
## What Changes
7+
8+
- Add an automated GitHub Actions workflow that mirrors the `frontend/` subtree to a configurable target repository.
9+
- Add a local shell helper script for the subtree-sync push logic so workflow behavior is explicit and reusable.
10+
- Document required repository secrets/variables and manual trigger behavior in `README.md`.
11+
12+
## Impact
13+
14+
- Affected surface: CI automation (`.github/workflows`) and documentation; no runtime behavior change for `gx`.
15+
- Operational requirement: a repository secret with push access to `Webu-PRO/guardex-frontend`.
16+
- Risk is moderate: mirror push is force-updated by subtree commit to keep target repo exactly aligned with `frontend/`.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
## ADDED Requirements
2+
3+
### Requirement: Frontend subtree mirror sync
4+
The repository SHALL provide an automated mirror flow that updates an external frontend repository from the `frontend/` subtree whenever qualifying changes land on the base branch.
5+
6+
#### Scenario: Sync runs after frontend changes on main
7+
- **WHEN** a commit is pushed to `main` and includes changes under `frontend/**`
8+
- **THEN** the mirror workflow runs
9+
- **AND** it computes a subtree commit from `frontend/`
10+
- **AND** it force-pushes that subtree commit to the configured target repo/branch.
11+
12+
#### Scenario: Manual sync run
13+
- **WHEN** an operator triggers the mirror workflow manually
14+
- **THEN** the workflow syncs the latest `frontend/` subtree to the configured target repo/branch even without a new push event.
15+
16+
#### Scenario: Missing credentials fails closed
17+
- **WHEN** the required mirror push token is missing
18+
- **THEN** the workflow fails with a clear configuration error
19+
- **AND** it does not attempt an anonymous or partial push.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
## 1. Specification
2+
3+
- [x] 1.1 Finalize proposal scope and acceptance criteria for frontend mirror sync.
4+
- [x] 1.2 Define normative requirements in `specs/frontend-mirror-sync/spec.md`.
5+
6+
## 2. Implementation
7+
8+
- [x] 2.1 Add subtree sync helper script for `frontend/` -> target repo branch push.
9+
- [x] 2.2 Add GitHub Actions workflow to run sync on `main` pushes that touch `frontend/**` and on manual dispatch.
10+
- [x] 2.3 Document setup requirements (secret + optional vars) and operator runbook in `README.md`.
11+
12+
## 3. Verification
13+
14+
- [x] 3.1 Run shell syntax checks for modified script/workflow support files.
15+
- [x] 3.2 Run `npm test`.
16+
- [x] 3.3 Run `openspec validate --specs`.
17+
18+
## 4. Cleanup
19+
20+
- [x] 4.1 Confirm task checklist reflects implemented state and known limitations.
21+
- [ ] 4.2 Merge the branch and clean up worktree/branch per repo policy.

scripts/sync-frontend-mirror.sh

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
TARGET_REPO="${TARGET_REPO:-}"
5+
TARGET_BRANCH="${TARGET_BRANCH:-main}"
6+
SOURCE_PREFIX="${SOURCE_PREFIX:-frontend}"
7+
SYNC_TOKEN="${SYNC_TOKEN:-${GITHUB_TOKEN:-}}"
8+
9+
usage() {
10+
cat <<'EOF'
11+
Usage: sync-frontend-mirror.sh [options]
12+
13+
Options:
14+
--repo <owner/name> Target GitHub repository (default: $TARGET_REPO)
15+
--branch <name> Target branch in the mirror repository (default: main)
16+
--source-prefix <path> Subtree path to mirror (default: frontend)
17+
--token <token> GitHub token with push access to target repo
18+
-h, --help Show this help
19+
EOF
20+
}
21+
22+
while [[ $# -gt 0 ]]; do
23+
case "$1" in
24+
--repo)
25+
TARGET_REPO="${2:-}"
26+
shift 2
27+
;;
28+
--branch)
29+
TARGET_BRANCH="${2:-}"
30+
shift 2
31+
;;
32+
--source-prefix)
33+
SOURCE_PREFIX="${2:-}"
34+
shift 2
35+
;;
36+
--token)
37+
SYNC_TOKEN="${2:-}"
38+
shift 2
39+
;;
40+
-h|--help)
41+
usage
42+
exit 0
43+
;;
44+
*)
45+
echo "[frontend-mirror-sync] Unknown argument: $1" >&2
46+
usage >&2
47+
exit 1
48+
;;
49+
esac
50+
done
51+
52+
if [[ -z "$TARGET_REPO" ]]; then
53+
echo "[frontend-mirror-sync] Missing target repository. Set --repo or TARGET_REPO." >&2
54+
exit 1
55+
fi
56+
57+
if [[ -z "$SYNC_TOKEN" ]]; then
58+
echo "[frontend-mirror-sync] Missing token. Set --token, SYNC_TOKEN, or GITHUB_TOKEN." >&2
59+
exit 1
60+
fi
61+
62+
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
63+
echo "[frontend-mirror-sync] Not inside a git repository." >&2
64+
exit 1
65+
fi
66+
67+
repo_root="$(git rev-parse --show-toplevel)"
68+
cd "$repo_root"
69+
70+
if [[ ! -d "$SOURCE_PREFIX" ]]; then
71+
echo "[frontend-mirror-sync] Source prefix not found: ${SOURCE_PREFIX}" >&2
72+
exit 1
73+
fi
74+
75+
if ! split_sha="$(git subtree split --prefix="$SOURCE_PREFIX" HEAD 2>/dev/null)"; then
76+
echo "[frontend-mirror-sync] Failed to compute subtree split for '${SOURCE_PREFIX}'." >&2
77+
exit 1
78+
fi
79+
80+
remote_url="https://x-access-token:${SYNC_TOKEN}@github.com/${TARGET_REPO}.git"
81+
push_output=""
82+
if ! push_output="$(git push --force "$remote_url" "${split_sha}:${TARGET_BRANCH}" 2>&1)"; then
83+
sanitized_output="$push_output"
84+
if [[ -n "$SYNC_TOKEN" ]]; then
85+
sanitized_output="${sanitized_output//${SYNC_TOKEN}/***}"
86+
fi
87+
echo "[frontend-mirror-sync] Push failed for ${TARGET_REPO}:${TARGET_BRANCH}." >&2
88+
echo "$sanitized_output" >&2
89+
exit 1
90+
fi
91+
92+
echo "[frontend-mirror-sync] Synced ${SOURCE_PREFIX} (commit ${split_sha}) -> ${TARGET_REPO}:${TARGET_BRANCH}"

0 commit comments

Comments
 (0)