From 145473c4f54da6cf7d2594ecc285eabe1ac44199 Mon Sep 17 00:00:00 2001 From: toki Date: Thu, 11 Jun 2026 14:07:31 +0900 Subject: [PATCH] update: sync-upstream script and agent-ops rules --- README.md | 2 + .../project/domain/core-service/rules.md | 1 + .../project/domain/workspace-ops/rules.md | 2 + agent-ops/rules/project/rules.md | 1 + bin/dev | 1 + bin/sync-upstream | 61 +++++++++++++++++++ 6 files changed, 68 insertions(+) create mode 100755 bin/sync-upstream diff --git a/README.md b/README.md index 0f836c28..61802055 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,7 @@ Postgres를 host에 publish하지 않고 compose network 내부 `db:5432`로만 | `apps/mattermost/` | Mattermost 모바일 앱 저장소 스냅샷 | | `services/core/` | Mattermost 서버 저장소 clone과 현재 compose 런타임 | | `services/push-proxy/` | Mattermost push-proxy 저장소 스냅샷 | +| `.upstream/mattermost/` | ignored Mattermost 원본 저장소 staging clone | | `docs/` | 모듈 간 제품, migration, 운영 문서 | | `bin/` | workspace helper 진입점 | | `agent-ops/` | agent 규칙, domain rule, 공통 skill 진입점 | @@ -107,6 +108,7 @@ Postgres를 host에 publish하지 않고 compose network 내부 `db:5432`로만 - `apps/mattermost`, `services/core`, `services/push-proxy`는 Mattermost 원본 저장소 clone으로 본다. nexo 소유 앱이나 독자 서버 제품으로 재정의하지 않는다. - 명시적인 업스트림 결정 없이 `services/core/UPSTREAM.md`의 기준선 정보를 바꾸지 않는다. - 업스트림 작업 clone은 이 저장소 안의 ignored `.upstream/mattermost/` staging 폴더에 원본 저장소별로 둔다. +- `bin/sync-upstream`은 `.upstream/mattermost/` clone 생성과 fast-forward 갱신만 담당하며, snapshot target으로 자동 복사하지 않는다. - 업스트림 저장소는 기록된 branch를 따라간다. `mattermost-mobile`은 `main`, `mattermost`와 `mattermost-push-proxy`는 `master`를 기준으로 하며, branch 변경 시점이나 의도적으로 정한 갱신 시점에 스냅샷을 떠서 이 저장소로 merge 요청한다. - 이 저장소에 들어오는 스냅샷은 원본 저장소별 정확한 commit SHA를 기록한다. - merge 요청은 원칙적으로 업스트림 저장소별로 분리한다. `apps/mattermost`, `services/core`, `services/push-proxy` 스냅샷을 한 요청에 섞지 않는다. diff --git a/agent-ops/rules/project/domain/core-service/rules.md b/agent-ops/rules/project/domain/core-service/rules.md index a5246231..a2a95d2d 100644 --- a/agent-ops/rules/project/domain/core-service/rules.md +++ b/agent-ops/rules/project/domain/core-service/rules.md @@ -41,6 +41,7 @@ Mattermost 서버 repository clone을 담당한다. `packages/messaging_flutter` - upstream에서 온 구조와 명명은 필요한 경우에만 변경한다. - 제품 특화 변경은 `packages/messaging_flutter` 검증에 필요한 범위로 좁게 유지하고, upstream 재동기화를 방해하지 않게 설명 가능한 단위로 남긴다. - upstream 작업 clone은 이 저장소 안의 ignored `.upstream/mattermost/` staging 폴더에 둔다. +- `bin/sync-upstream`은 staging clone 갱신까지만 수행하고, `services/core` snapshot 반영은 별도 diff/smoke 확인 뒤 진행한다. - staging clone은 Mattermost server upstream `master`를 따라가며, `master` 변경 시점 또는 의도적으로 정한 refresh 시점에 snapshot을 떠서 이 저장소의 `services/core`로 merge 요청한다. - `services/core` snapshot 반영 시 upstream commit SHA를 `services/core/UPSTREAM.md`에 기록한다. - `services/core` snapshot merge 요청은 앱 또는 push-proxy snapshot과 섞지 않는다. diff --git a/agent-ops/rules/project/domain/workspace-ops/rules.md b/agent-ops/rules/project/domain/workspace-ops/rules.md index c006e05d..ee58ca5b 100644 --- a/agent-ops/rules/project/domain/workspace-ops/rules.md +++ b/agent-ops/rules/project/domain/workspace-ops/rules.md @@ -36,6 +36,7 @@ last_rule_updated_at: 2026-06-01 - `bin/lint` — Flutter analyze와 선택적 Go vet 실행 - `bin/build` — Flutter web build와 선택적 Go build 실행 - `bin/dev` — 개발 entrypoint 안내 +- `bin/sync-upstream` — ignored `.upstream/mattermost/` 원본 clone 생성과 fast-forward 갱신 - `bin/publish-runtime-images` — nexo-owned runtime image build/publish wrapper - `docs/runtime-image-validation.md` — runtime image registry, tag, digest evidence 문서 - `agent-roadmap/current.md` — 활성 Phase와 Milestone 후보 목록 @@ -44,6 +45,7 @@ last_rule_updated_at: 2026-06-01 ## 유지할 패턴 - root helper script는 모듈별 command를 얇게 묶는 역할로 유지한다. +- upstream staging helper는 `.upstream/mattermost/` clone 갱신만 담당하고, tracked snapshot target으로 자동 복사하지 않는다. - runtime image publish wrapper는 core/push-proxy build와 registry publish를 orchestration하되, 각 서비스의 내부 소스 책임을 가져오지 않는다. - 로컬 도구가 없을 때 skip하는 기존 동작을 보존하고, skip된 검증은 작업 보고에 명시한다. - 여러 모듈에 걸친 문서는 `docs/`에 두고, 모듈 내부만 해당하는 설명은 해당 모듈 README나 docs에 둔다. diff --git a/agent-ops/rules/project/rules.md b/agent-ops/rules/project/rules.md index 76a41099..8ae05320 100644 --- a/agent-ops/rules/project/rules.md +++ b/agent-ops/rules/project/rules.md @@ -36,6 +36,7 @@ Mattermost 원본은 앱, 서버, push 서버 repository clone 단위로 둔다. - `apps/flutter-test/`는 플러그인 integration 검증용 앱으로만 본다. 플러그인 integration 검증을 넘는 제품 기능을 키우지 않는다. - `apps/mattermost`, `services/core`, `services/push-proxy`는 Mattermost 원본 repository clone으로 유지한다. nexo 제품 앱이나 독자 서버 제품으로 재정의하지 않는다. - upstream 작업 clone은 이 저장소 안의 ignored `.upstream/mattermost/` staging 폴더에 원본 repository별로 둔다. +- `bin/sync-upstream`은 `.upstream/mattermost/` clone 생성과 fast-forward 갱신만 담당하며, snapshot target으로 자동 복사하지 않는다. - staging clone은 repository별 기록된 upstream branch를 따라간다. `mattermost-mobile`은 `main`, `mattermost`와 `mattermost-push-proxy`는 `master`를 기준으로 하며, 해당 branch 변경 시점 또는 의도적으로 정한 refresh 시점에 snapshot을 떠서 이 저장소로 merge 요청한다. - 이 저장소에 들어오는 snapshot은 원본 repository별 commit SHA를 기록한다. - merge 요청은 원칙적으로 upstream repository별로 분리한다. 앱, 서버, push-proxy snapshot을 한 요청에 섞지 않는다. diff --git a/bin/dev b/bin/dev index cd5d1d1a..5e9ea8dc 100755 --- a/bin/dev +++ b/bin/dev @@ -9,6 +9,7 @@ nexo development entrypoints: flutter-test host: cd "$root/apps/flutter-test" && flutter run plugin package: cd "$root/packages/messaging_flutter" && flutter test core compose: cd "$root/services/core/compose" && docker compose up + upstream staging: $root/bin/sync-upstream Start only the pieces you need. EOF diff --git a/bin/sync-upstream b/bin/sync-upstream new file mode 100755 index 00000000..1a7862c4 --- /dev/null +++ b/bin/sync-upstream @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +set -euo pipefail + +root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +staging_root="${NEXO_UPSTREAM_ROOT:-"$root/.upstream/mattermost"}" + +preflight_repo() { + local name="$1" + local dir="$staging_root/$name" + + if [ -d "$dir/.git" ]; then + if [ -n "$(git -C "$dir" status --porcelain)" ]; then + echo "refuse dirty upstream staging clone: $dir" >&2 + exit 1 + fi + elif [ -e "$dir" ]; then + echo "refuse non-git upstream staging path: $dir" >&2 + exit 1 + fi +} + +sync_repo() { + local name="$1" + local url="$2" + local branch="$3" + local target="$4" + local dir="$staging_root/$name" + + mkdir -p "$staging_root" + + if [ -d "$dir/.git" ]; then + git -C "$dir" checkout -q "$branch" + git -C "$dir" pull --ff-only --depth 1 origin "$branch" + else + git clone --depth 1 --single-branch --branch "$branch" "$url" "$dir" + fi + + local commit + commit="$(git -C "$dir" rev-parse HEAD)" + echo "$name" + echo " source: $url" + echo " branch: $branch" + echo " commit: $commit" + echo " staging: ${dir#"$root"/}" + echo " snapshot target: $target" +} + +preflight_repo "mattermost" +preflight_repo "mattermost-mobile" +preflight_repo "mattermost-push-proxy" + +sync_repo "mattermost" "https://github.com/mattermost/mattermost.git" "master" "services/core/" +sync_repo "mattermost-mobile" "https://github.com/mattermost/mattermost-mobile.git" "main" "apps/mattermost/" +sync_repo "mattermost-push-proxy" "https://github.com/mattermost/mattermost-push-proxy.git" "master" "services/push-proxy/" + +cat <