feat: runtime image validation & domain rules update
- Add mattermost-app and push-proxy-service domain rules - Add bin/publish-runtime-images script - Add runtime-image-validation documentation - Update agent-ops domain rules and project rules - Remove outdated 01_image_publish task files - Update docs/README.md
This commit is contained in:
parent
4b0222479d
commit
6ca7989169
12 changed files with 333 additions and 265 deletions
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
domain: client-app
|
||||
last_rule_review_commit: c9183529d81f9b7ef458460c7195887e64f1eddb
|
||||
last_rule_updated_at: 2026-05-27
|
||||
last_rule_review_commit: 4b0222479d9ab67093ab82ccdd31af146c73e1e4
|
||||
last_rule_updated_at: 2026-05-28
|
||||
---
|
||||
|
||||
# client-app
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
domain: core-service
|
||||
last_rule_review_commit: c9183529d81f9b7ef458460c7195887e64f1eddb
|
||||
last_rule_updated_at: 2026-05-27
|
||||
last_rule_review_commit: 4b0222479d9ab67093ab82ccdd31af146c73e1e4
|
||||
last_rule_updated_at: 2026-05-28
|
||||
---
|
||||
|
||||
# core-service
|
||||
|
|
@ -14,6 +14,7 @@ Mattermost 서버 repository clone을 담당한다. `packages/messaging_flutter`
|
|||
|
||||
- `services/core/` — Mattermost 서버 repository clone
|
||||
- `services/core/server/` — Mattermost server module
|
||||
- `services/core/webapp/` — Mattermost webapp module
|
||||
- `services/core/api/` — API reference tooling
|
||||
- `services/core/compose/` — local core runtime Docker Compose
|
||||
- `services/core/e2e-tests/`, `services/core/tools/` — core 검증 및 보조 도구
|
||||
|
|
@ -30,6 +31,7 @@ Mattermost 서버 repository clone을 담당한다. `packages/messaging_flutter`
|
|||
## 주요 구성 요소
|
||||
|
||||
- `services/core/server/go.mod` — server Go module 기준
|
||||
- `services/core/webapp/channels/` — Mattermost web client source 기준
|
||||
- `services/core/api/package.json` — API reference tooling 기준
|
||||
- `services/core/compose/docker-compose.yml` — local core 서비스 구성
|
||||
|
||||
|
|
|
|||
60
agent-ops/rules/project/domain/mattermost-app/rules.md
Normal file
60
agent-ops/rules/project/domain/mattermost-app/rules.md
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
---
|
||||
domain: mattermost-app
|
||||
last_rule_review_commit: 4b0222479d9ab67093ab82ccdd31af146c73e1e4
|
||||
last_rule_updated_at: 2026-05-28
|
||||
---
|
||||
|
||||
# mattermost-app
|
||||
|
||||
## 목적 / 책임
|
||||
|
||||
`apps/mattermost`는 Mattermost mobile 원본 repository clone을 담당한다. nexo 제품 앱으로 재정의하지 않고, runtime 검증과 upstream-followable snapshot 기준을 제공하는 앱 clone으로 유지한다.
|
||||
|
||||
## 포함 경로
|
||||
|
||||
- `apps/mattermost/` — Mattermost mobile repository snapshot
|
||||
- `apps/mattermost/app/` — React Native app source
|
||||
- `apps/mattermost/android/`, `apps/mattermost/ios/` — native mobile app projects
|
||||
- `apps/mattermost/libraries/`, `apps/mattermost/share_extension/` — bundled mobile support packages and share extension
|
||||
- `apps/mattermost/test/`, `apps/mattermost/detox/` — app test and e2e tooling
|
||||
- `apps/mattermost/package.json` — React Native/Expo package metadata
|
||||
- `apps/mattermost/UPSTREAM.md` — upstream baseline 기록
|
||||
|
||||
## 제외 경로
|
||||
|
||||
- `packages/messaging_flutter/` — nexo Flutter push plugin 책임
|
||||
- `apps/flutter-test/` — plugin 검증용 Flutter test host 책임
|
||||
- `services/core/` — Mattermost server/webapp runtime 책임
|
||||
- `services/push-proxy/` — Mattermost push-proxy service 책임
|
||||
- `docs/`, `bin/` — workspace 공통 문서와 command 책임
|
||||
|
||||
## 주요 구성 요소
|
||||
|
||||
- `apps/mattermost/package.json` — Mattermost Mobile React Native/Expo toolchain 기준
|
||||
- `apps/mattermost/app/` — mobile application source
|
||||
- `apps/mattermost/android/`, `apps/mattermost/ios/` — Android/iOS native project 기준
|
||||
- `apps/mattermost/detox/` — mobile e2e test harness
|
||||
- `apps/mattermost/UPSTREAM.md` — source repository, branch, snapshot commit 기록
|
||||
|
||||
## 유지할 패턴
|
||||
|
||||
- upstream branch는 Mattermost mobile `main` 기준으로 추적하고, snapshot commit은 `apps/mattermost/UPSTREAM.md`에 기록한다.
|
||||
- 이 도메인은 원본 Mattermost 앱 clone으로 유지하며 nexo 제품 앱 UI나 business logic을 추가하지 않는다.
|
||||
- runtime image 검증에서 이 앱을 사용할 때는 smoke/e2e evidence를 남기고, 앱 내부 제품 방향 변경으로 확장하지 않는다.
|
||||
- upstream snapshot 반영은 서버나 push-proxy snapshot과 섞지 않고 별도 작업 단위로 다룬다.
|
||||
- nexo-specific patch가 필요하면 가능한 한 snapshot 밖의 문서, wrapper, 작은 명시 patch로 둔다.
|
||||
|
||||
## 다른 도메인과의 경계
|
||||
|
||||
- **messaging-flutter**: Flutter plugin API와 native notification implementation은 `packages/messaging_flutter`가 소유하며, Mattermost mobile app의 React Native push 구현을 plugin source of truth로 옮기지 않는다.
|
||||
- **client-app**: `apps/flutter-test`는 Flutter plugin 검증 host이고, `apps/mattermost`는 upstream Mattermost mobile clone이다.
|
||||
- **core-service**: server/webapp runtime은 `services/core`가 소유하며, Mattermost app은 해당 runtime에 접속하는 검증 소비자 역할만 한다.
|
||||
- **push-proxy-service**: push notification proxy server는 `services/push-proxy`가 소유한다.
|
||||
- **workspace-ops**: workspace script와 docs가 app smoke/e2e 흐름을 호출할 수 있지만 app 내부 구조와 upstream snapshot 정책은 이 도메인이 소유한다.
|
||||
|
||||
## 금지 사항
|
||||
|
||||
- `apps/mattermost/UPSTREAM.md` baseline을 근거 없이 변경하지 않는다.
|
||||
- 이 도메인을 nexo 제품 앱 또는 Flutter plugin host로 재정의하지 않는다.
|
||||
- upstream-owned 파일에 대량 rename, formatting-only churn, 광범위 재배치를 작업 범위 없이 수행하지 않는다.
|
||||
- generated/build/cache 산출물을 소스 변경처럼 다루지 않는다.
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
domain: messaging-flutter
|
||||
last_rule_review_commit: c9183529d81f9b7ef458460c7195887e64f1eddb
|
||||
last_rule_updated_at: 2026-05-27
|
||||
last_rule_review_commit: 4b0222479d9ab67093ab82ccdd31af146c73e1e4
|
||||
last_rule_updated_at: 2026-05-28
|
||||
---
|
||||
|
||||
# messaging-flutter
|
||||
|
|
|
|||
62
agent-ops/rules/project/domain/push-proxy-service/rules.md
Normal file
62
agent-ops/rules/project/domain/push-proxy-service/rules.md
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
---
|
||||
domain: push-proxy-service
|
||||
last_rule_review_commit: 4b0222479d9ab67093ab82ccdd31af146c73e1e4
|
||||
last_rule_updated_at: 2026-05-28
|
||||
---
|
||||
|
||||
# push-proxy-service
|
||||
|
||||
## 목적 / 책임
|
||||
|
||||
`services/push-proxy`는 Mattermost push-proxy 원본 repository clone을 담당한다. nexo runtime image 검증에 쓰이더라도 원본 push notification proxy service로 유지하고, upstream-followable snapshot 기준을 보존한다.
|
||||
|
||||
## 포함 경로
|
||||
|
||||
- `services/push-proxy/` — Mattermost push-proxy repository snapshot
|
||||
- `services/push-proxy/server/` — Android/APNs notification server, config, metrics, HTTP server implementation
|
||||
- `services/push-proxy/config/` — sample push-proxy configuration
|
||||
- `services/push-proxy/docker/` — container image build definitions
|
||||
- `services/push-proxy/internal/` — internal version package
|
||||
- `services/push-proxy/swagger/` — push-proxy API spec tooling
|
||||
- `services/push-proxy/go.mod`, `services/push-proxy/Makefile` — Go module and release/build entrypoints
|
||||
- `services/push-proxy/UPSTREAM.md` — upstream baseline 기록
|
||||
|
||||
## 제외 경로
|
||||
|
||||
- `services/core/` — Mattermost server/webapp runtime 책임
|
||||
- `packages/messaging_flutter/` — Flutter push plugin 책임
|
||||
- `apps/flutter-test/` — plugin 검증용 Flutter test host 책임
|
||||
- `apps/mattermost/` — Mattermost mobile app clone 책임
|
||||
- `docs/`, `bin/` — workspace 공통 문서와 command 책임
|
||||
|
||||
## 주요 구성 요소
|
||||
|
||||
- `services/push-proxy/main.go` — push-proxy process entrypoint
|
||||
- `services/push-proxy/server/android_notification_server.go` — FCM notification delivery path
|
||||
- `services/push-proxy/server/apple_notification_server.go` — APNs notification delivery path
|
||||
- `services/push-proxy/server/config_push_proxy.go` — push-proxy configuration loading
|
||||
- `services/push-proxy/server/metrics.go` — metrics exposure
|
||||
- `services/push-proxy/docker/Dockerfile` — runtime image build 기준
|
||||
- `services/push-proxy/UPSTREAM.md` — source repository, branch, snapshot commit 기록
|
||||
|
||||
## 유지할 패턴
|
||||
|
||||
- upstream branch는 Mattermost push-proxy `master` 기준으로 추적하고, snapshot commit은 `services/push-proxy/UPSTREAM.md`에 기록한다.
|
||||
- 이 도메인은 push notification proxy server clone으로 유지하며 nexo 독자 서버 제품으로 재정의하지 않는다.
|
||||
- runtime image build는 `services/push-proxy/docker/`와 Go module 기준을 사용하고, publish orchestration은 workspace-ops wrapper가 담당할 수 있다.
|
||||
- upstream snapshot 반영은 app 또는 core snapshot과 섞지 않고 별도 작업 단위로 다룬다.
|
||||
- nexo-specific patch가 필요하면 가능한 한 snapshot 밖의 compose, 문서, wrapper, 작은 명시 patch로 둔다.
|
||||
|
||||
## 다른 도메인과의 경계
|
||||
|
||||
- **core-service**: Mattermost server runtime은 `services/core`가 소유하며, push-proxy는 server가 위임하는 push notification delivery endpoint 역할을 한다.
|
||||
- **messaging-flutter**: device token 저장, native notification 표시, ACK/open/reply 처리는 Flutter plugin이 소유하며, push-proxy는 Android/APNs push 전달 서버 역할만 한다.
|
||||
- **mattermost-app**: Mattermost mobile app은 push-proxy를 필요로 하는 client clone이며, push-proxy server 구현을 소유하지 않는다.
|
||||
- **workspace-ops**: workspace wrapper가 image build/publish를 호출할 수 있지만 push-proxy server 구현과 Dockerfile 기준은 이 도메인이 소유한다.
|
||||
|
||||
## 금지 사항
|
||||
|
||||
- `services/push-proxy/UPSTREAM.md` baseline을 근거 없이 변경하지 않는다.
|
||||
- 이 도메인을 `services/core` 하위 구성 요소로 흡수하거나 nexo 독자 서버 제품으로 확장하지 않는다.
|
||||
- upstream-owned 파일에 대량 rename, formatting-only churn, 광범위 재배치를 작업 범위 없이 수행하지 않는다.
|
||||
- generated/build/cache 산출물을 소스 변경처럼 다루지 않는다.
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
domain: workspace-ops
|
||||
last_rule_review_commit: c9183529d81f9b7ef458460c7195887e64f1eddb
|
||||
last_rule_updated_at: 2026-05-27
|
||||
last_rule_review_commit: 4b0222479d9ab67093ab82ccdd31af146c73e1e4
|
||||
last_rule_updated_at: 2026-05-28
|
||||
---
|
||||
|
||||
# workspace-ops
|
||||
|
|
@ -33,10 +33,13 @@ last_rule_updated_at: 2026-05-27
|
|||
- `bin/lint` — Flutter analyze와 선택적 Go vet 실행
|
||||
- `bin/build` — Flutter web build와 선택적 Go build 실행
|
||||
- `bin/dev` — 개발 entrypoint 안내
|
||||
- `bin/publish-runtime-images` — nexo-owned runtime image build/publish wrapper
|
||||
- `docs/runtime-image-validation.md` — runtime image registry, tag, digest evidence 문서
|
||||
|
||||
## 유지할 패턴
|
||||
|
||||
- root helper script는 모듈별 command를 얇게 묶는 역할로 유지한다.
|
||||
- runtime image publish wrapper는 core/push-proxy build와 registry publish를 orchestration하되, 각 서비스의 내부 소스 책임을 가져오지 않는다.
|
||||
- 로컬 도구가 없을 때 skip하는 기존 동작을 보존하고, skip된 검증은 작업 보고에 명시한다.
|
||||
- 여러 모듈에 걸친 문서는 `docs/`에 두고, 모듈 내부만 해당하는 설명은 해당 모듈 README나 docs에 둔다.
|
||||
- 프로젝트 전용 agent-ops 파일만 수정하고 common 파일은 원본 framework에서 동기화한다.
|
||||
|
|
@ -46,6 +49,8 @@ last_rule_updated_at: 2026-05-27
|
|||
- **core-service**: workspace script가 core 검증을 호출할 수 있지만 core 내부 명령 선택은 core 규칙을 따른다.
|
||||
- **messaging-flutter**: plugin 검증은 workspace script로 실행할 수 있으나 API/플랫폼 계약은 plugin 도메인이 소유한다.
|
||||
- **client-app**: `flutter-test` 검증 앱은 workspace script로 실행할 수 있으나 host behavior는 client 도메인이 소유한다.
|
||||
- **mattermost-app**: workspace 문서가 upstream snapshot과 smoke/e2e evidence를 연결할 수 있지만 app 내부 구조와 React Native 앱 정책은 mattermost-app 도메인이 소유한다.
|
||||
- **push-proxy-service**: workspace wrapper가 image publish를 호출할 수 있지만 push-proxy server 구현과 Dockerfile 기준은 push-proxy-service 도메인이 소유한다.
|
||||
|
||||
## 금지 사항
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,9 @@ Mattermost 원본은 앱, 서버, push 서버 repository clone 단위로 둔다.
|
|||
- Android native plugin: Kotlin, Java, Gradle
|
||||
- iOS / macOS plugin scaffold: Swift
|
||||
- Server core: Go `1.24.13`, messaging server module
|
||||
- Mattermost app/API tooling: Node.js, npm workspaces, TypeScript, Redocly
|
||||
- Mattermost mobile app: React Native `0.83.9`, Expo `55`, Node.js, npm, TypeScript, Detox
|
||||
- Mattermost API tooling: Node.js, npm workspaces, TypeScript, Redocly
|
||||
- Push proxy: Go `1.24.6`, Docker
|
||||
- Local runtime: Docker Compose under `services/core/compose/`
|
||||
|
||||
## 작업 원칙
|
||||
|
|
@ -57,6 +59,11 @@ Mattermost 원본은 앱, 서버, push 서버 repository clone 단위로 둔다.
|
|||
|
||||
`bin/*` 명령은 로컬 도구가 없으면 일부 검증을 skip할 수 있다. skip 출력이 있으면 최종 보고에 명시한다.
|
||||
|
||||
## 도메인 룰 로딩
|
||||
|
||||
- 아래 도메인 매핑에 해당하는 작업에서 해당 domain 최초 진입 시 domain rule을 1회 읽는다.
|
||||
- 이미 읽은 domain rule은 같은 세션에서 반복해서 읽지 않는다.
|
||||
|
||||
## 도메인 매핑
|
||||
|
||||
| 경로 패턴 | 도메인 | rules.md |
|
||||
|
|
@ -64,8 +71,8 @@ Mattermost 원본은 앱, 서버, push 서버 repository clone 단위로 둔다.
|
|||
| `services/core/**` | core-service | `agent-ops/rules/project/domain/core-service/rules.md` |
|
||||
| `packages/messaging_flutter/**` | messaging-flutter | `agent-ops/rules/project/domain/messaging-flutter/rules.md` |
|
||||
| `apps/flutter-test/**` | client-app | `agent-ops/rules/project/domain/client-app/rules.md` |
|
||||
| `apps/mattermost/**` | mattermost-app | 생성 예정 |
|
||||
| `services/push-proxy/**` | push-proxy-service | 생성 예정 |
|
||||
| `apps/mattermost/**` | mattermost-app | `agent-ops/rules/project/domain/mattermost-app/rules.md` |
|
||||
| `services/push-proxy/**` | push-proxy-service | `agent-ops/rules/project/domain/push-proxy-service/rules.md` |
|
||||
| `docs/**`, `bin/**`, root docs/config | workspace-ops | `agent-ops/rules/project/domain/workspace-ops/rules.md` |
|
||||
|
||||
## 스킬 라우팅
|
||||
|
|
|
|||
|
|
@ -1,119 +0,0 @@
|
|||
<!-- task=m-runtime-image-validation/01_image_publish plan=0 tag=IMG -->
|
||||
|
||||
# Code Review Reference - IMG
|
||||
|
||||
> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.**
|
||||
> The task is NOT complete until every implementation-owned section below is filled in.
|
||||
> Complete the `구현 체크리스트`; the final checklist item is mandatory before saving.
|
||||
> Fill implementation-owned sections, then stop with active files in place and report ready for review.
|
||||
> If implementation is blocked by a user-only decision, external environment prerequisite, or scope conflict, fill `사용자 리뷰 요청` with evidence and stop with active files in place; code-review decides whether to write `USER_REVIEW.md`.
|
||||
> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume.
|
||||
> Follow the ownership table at the bottom of this file for which sections you own.
|
||||
|
||||
## 개요
|
||||
|
||||
date=2026-05-28
|
||||
task=m-runtime-image-validation/01_image_publish, plan=0, tag=IMG
|
||||
|
||||
## 이 파일을 읽는 리뷰 에이전트에게
|
||||
|
||||
> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다.
|
||||
|
||||
각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
|
||||
리뷰 완료는 아래 순서까지 끝난 상태를 의미합니다.
|
||||
|
||||
1. 판정을 append한다.
|
||||
2. `CODE_REVIEW-cloud-G07.md` -> `code_review_cloud_G07_N.log`, `PLAN-cloud-G07.md` -> `plan_cloud_G07_M.log`로 아카이브한다.
|
||||
3. PASS이면 `complete.log` 작성 후 active task 디렉터리를 `agent-task/archive/YYYY/MM/m-runtime-image-validation/01_image_publish/`로 이동한다. WARN/FAIL이면 user-review gate를 확인한 뒤 다음 active plan/review 파일 또는 `USER_REVIEW.md`를 작성한다.
|
||||
4. PASS이고 task group이 `m-runtime-image-validation`이면 완료 이벤트 메타데이터를 보고하고 roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다.
|
||||
5. 적용 가능한 `코드리뷰 전용 체크리스트` 항목을 최종 `.log` 위치에서 체크한 뒤 보고한다.
|
||||
|
||||
---
|
||||
|
||||
## 구현 항목별 완료 여부
|
||||
|
||||
| 항목 | 완료 여부 |
|
||||
|------|---------|
|
||||
| [IMG-1] Mac ARM64 image publish wrapper와 evidence 문서 | [ ] |
|
||||
| [IMG-2] nexo-owned latest image publish와 digest evidence | [ ] |
|
||||
|
||||
## 구현 체크리스트
|
||||
|
||||
- [ ] [IMG-1] Mac ARM64 image publish wrapper와 evidence 문서를 추가한다.
|
||||
- [ ] [IMG-2] `toki-labs.com:5050/nexo/mattermost:latest`와 `toki-labs.com:5050/nexo/push-proxy:latest`를 검증 완료 stable image로 publish하고 digest evidence를 기록한다.
|
||||
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.
|
||||
|
||||
## 코드리뷰 전용 체크리스트
|
||||
|
||||
> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다.
|
||||
> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다.
|
||||
|
||||
- [ ] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다.
|
||||
- [ ] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다.
|
||||
- [ ] active `CODE_REVIEW-cloud-G07.md`를 `code_review_cloud_G07_N.log`로 아카이브한다.
|
||||
- [ ] active `PLAN-cloud-G07.md`를 `plan_cloud_G07_M.log`로 아카이브한다.
|
||||
- [ ] PASS이면 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다.
|
||||
- [ ] PASS이면 active task 디렉터리를 `agent-task/archive/YYYY/MM/m-runtime-image-validation/01_image_publish/`로 이동한다.
|
||||
- [ ] PASS이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고 roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다.
|
||||
- [ ] WARN/FAIL이면 다음 active plan/review 또는 `USER_REVIEW.md`를 작성하고 `complete.log`를 작성하지 않는다.
|
||||
|
||||
## 계획 대비 변경 사항
|
||||
|
||||
_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._
|
||||
|
||||
## 주요 설계 결정
|
||||
|
||||
_구현 에이전트가 주요 설계 결정 사항을 기록한다._
|
||||
|
||||
## 사용자 리뷰 요청
|
||||
|
||||
_기본값은 `없음`이다. 구현 중 사용자 결정, 외부 환경 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다. code-review가 이 내용을 검증해 `USER_REVIEW.md`를 작성한다._
|
||||
|
||||
- 상태: 없음
|
||||
- 사유 유형: 없음
|
||||
- 결정 필요: 없음
|
||||
- 차단 근거: 없음
|
||||
- 실행한 검증/명령: 없음
|
||||
- 재개 조건: 없음
|
||||
|
||||
## 리뷰어를 위한 체크포인트
|
||||
|
||||
- `latest`가 최신 빌드가 아니라 검증 완료 stable pointer로만 promote됐는지 확인한다.
|
||||
- published manifest가 `linux/arm64`인지, digest가 evidence 문서와 일치하는지 확인한다.
|
||||
- wrapper가 secrets를 repo에 쓰지 않고 원격 임시 파일을 정리하는지 확인한다.
|
||||
|
||||
## 검증 결과
|
||||
|
||||
_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._
|
||||
|
||||
### IMG-1 중간 검증
|
||||
```sh
|
||||
$ bash -n bin/publish-runtime-images
|
||||
(output)
|
||||
$ rg --sort path -n "toki-labs.com:5050|linux/arm64|latest|digest" bin docs
|
||||
(output)
|
||||
```
|
||||
|
||||
### IMG-2 중간 검증
|
||||
```sh
|
||||
$ curl -fsS https://toki-labs.com:5050/v2/_catalog
|
||||
(output)
|
||||
$ ssh toki@toki-labs.com '/usr/local/bin/docker manifest inspect toki-labs.com:5050/nexo/mattermost:latest >/tmp/nexo-mm-latest.manifest.json && /usr/local/bin/docker manifest inspect toki-labs.com:5050/nexo/push-proxy:latest >/tmp/nexo-push-latest.manifest.json && grep -H "\"architecture\": \"arm64\"" /tmp/nexo-*-latest.manifest.json'
|
||||
(output)
|
||||
```
|
||||
|
||||
### 최종 검증
|
||||
```sh
|
||||
$ bash -n bin/publish-runtime-images
|
||||
(output)
|
||||
$ rg --sort path -n "toki-labs.com:5050|linux/arm64|latest|digest|nexo/mattermost|nexo/push-proxy" bin docs
|
||||
(output)
|
||||
$ curl -fsS https://toki-labs.com:5050/v2/_catalog
|
||||
(output)
|
||||
$ ssh toki@toki-labs.com '/usr/local/bin/docker manifest inspect toki-labs.com:5050/nexo/mattermost:latest >/tmp/nexo-mm-latest.manifest.json && /usr/local/bin/docker manifest inspect toki-labs.com:5050/nexo/push-proxy:latest >/tmp/nexo-push-latest.manifest.json && grep -H "\"architecture\": \"arm64\"" /tmp/nexo-*-latest.manifest.json'
|
||||
(output)
|
||||
```
|
||||
|
||||
## 코드리뷰 결과
|
||||
|
||||
_리뷰 에이전트가 append한다._
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
<!-- task=m-runtime-image-validation/01_image_publish plan=0 tag=IMG -->
|
||||
|
||||
# Plan - IMG
|
||||
|
||||
## 이 파일을 읽는 구현 에이전트에게
|
||||
|
||||
`CODE_REVIEW-cloud-G07.md`의 구현 에이전트 소유 섹션을 반드시 실제 구현 내용과 검증 출력으로 채운다. 검증을 실행하고 active 파일을 그대로 둔 채 리뷰 준비를 보고한다. 사용자 결정, 외부 환경 준비, 범위 충돌 없이는 진행할 수 없으면 review stub의 `사용자 리뷰 요청` 섹션에 근거와 재개 조건을 채우고 중단한다. `USER_REVIEW.md`, log archive, `complete.log` 작성은 code-review 전용이다.
|
||||
|
||||
## 배경
|
||||
|
||||
Milestone은 원격 Mac 전용 `linux/arm64` 이미지를 `toki-labs.com:5050` registry에 배포하기로 결정됐다. 현재 compose는 upstream amd64/core image와 upstream latest push-proxy를 직접 사용하므로, 먼저 nexo-owned 이미지가 실제로 build/push/pull 되는 증거가 필요하다.
|
||||
|
||||
## 사용자 리뷰 요청 흐름
|
||||
|
||||
구현 중 차단 사항은 active `CODE_REVIEW-cloud-G07.md`의 `사용자 리뷰 요청` 섹션에 기록한다. code-review가 요청을 검증하고 실제 `USER_REVIEW.md` 작성 여부를 결정한다.
|
||||
|
||||
## 분석 결과
|
||||
|
||||
### 읽은 파일
|
||||
|
||||
- `agent-roadmap/current.md`
|
||||
- `agent-roadmap/phase/product-foundation/PHASE.md`
|
||||
- `agent-roadmap/phase/product-foundation/milestones/runtime-image-validation.md`
|
||||
- `agent-ops/rules/project/domain/workspace-ops/rules.md`
|
||||
- `agent-ops/rules/project/domain/core-service/rules.md`
|
||||
- `services/core/compose/docker-compose.yml`
|
||||
- `services/core/compose/README.md`
|
||||
- `services/core/compose/.env.example`
|
||||
- `services/core/UPSTREAM.md`
|
||||
- `services/core/server/build/Dockerfile`
|
||||
- `services/core/server/build/passwd`
|
||||
- `services/push-proxy/Makefile`
|
||||
- `services/push-proxy/docker/Dockerfile`
|
||||
- `services/push-proxy/docker/entrypoint`
|
||||
- `services/push-proxy/UPSTREAM.md`
|
||||
- `bin/test`
|
||||
- `bin/lint`
|
||||
- `bin/build`
|
||||
- 원격 `~/docker/services/nexo/compose/docker-compose.yml`
|
||||
|
||||
### 테스트 커버리지 공백
|
||||
|
||||
- 이미지 build/push/pull 경로는 기존 자동 테스트가 없다. 실제 검증은 원격 Mac의 `/usr/local/bin/docker`, registry API, `docker manifest inspect`, `docker image inspect` 출력으로 대체한다.
|
||||
- core image는 `services/core/server/build/Dockerfile`이 `MM_PACKAGE` URL을 받지만, 이 repo에는 nexo-owned publish wrapper가 없다.
|
||||
- push-proxy는 ARM64 build target이 있으나 Makefile의 기본 Docker run option은 `linux/amd64`이고 multi-arch target도 포함한다. 이번 작업은 Mac 전용 `linux/arm64`만 검증해야 한다.
|
||||
|
||||
### 심볼 참조
|
||||
|
||||
- none. 심볼 rename/remove 작업이 아니다.
|
||||
|
||||
### 분할 판단
|
||||
|
||||
Split policy를 먼저 평가했다. `m-runtime-image-validation` 아래 split work로 진행한다.
|
||||
- `01_image_publish`: nexo-owned image build/push/pull evidence를 만든다. 선행 없음.
|
||||
- `02+01_remote_compose`: 01 완료 후 compose를 nexo-owned `latest` image로 전환한다.
|
||||
- `03+02_validation_matrix`: 02 완료 후 repo와 consumer smoke/e2e evidence를 정리한다.
|
||||
|
||||
### 범위 결정 근거
|
||||
|
||||
- `services/core/UPSTREAM.md` baseline은 변경하지 않는다.
|
||||
- `services/core/server/`와 `services/push-proxy/` upstream source는 최소 wrapper/문서 외에는 수정하지 않는다.
|
||||
- registry auth, production hardening, multi-arch manifest, amd64 image는 Milestone 범위 제외다.
|
||||
- 원격 `~/docker/services/nexo/compose`는 이 task에서 전환하지 않는다. 이 task는 publish evidence까지만 만든다.
|
||||
|
||||
### 빌드 등급
|
||||
|
||||
- build=`cloud-G07`, review=`cloud-G07`. SSH, Docker build/push, registry API, stdout/stderr 계약이 성공 조건인 terminal-agent 작업이다.
|
||||
|
||||
## 구현 체크리스트
|
||||
|
||||
- [ ] [IMG-1] Mac ARM64 image publish wrapper와 evidence 문서를 추가한다.
|
||||
- [ ] [IMG-2] `toki-labs.com:5050/nexo/mattermost:latest`와 `toki-labs.com:5050/nexo/push-proxy:latest`를 검증 완료 stable image로 publish하고 digest evidence를 기록한다.
|
||||
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.
|
||||
|
||||
### [IMG-1] Publish Wrapper And Evidence Doc
|
||||
|
||||
문제: `services/core/compose/docker-compose.yml:27`은 `mattermost/mattermost-team-edition:11.4.2`, `:28`은 `linux/amd64`, `:58`은 `mattermost/mattermost-push-proxy:latest`를 직접 참조한다. 반복 가능한 nexo-owned image publish entrypoint와 evidence 문서가 없다.
|
||||
|
||||
해결 방법: root `bin/`에 얇은 publish wrapper를 추가하고, `docs/runtime-image-validation.md`에 registry/tag/architecture/evidence 표를 만든다. wrapper는 기본값을 `toki-labs.com:5050`, `linux/arm64`, `nexo/mattermost`, `nexo/push-proxy`로 둔다. core는 `services/core/server/build/Dockerfile`에 `MM_PACKAGE=https://releases.mattermost.com/11.4.2/mattermost-team-11.4.2-linux-arm64.tar.gz`를 넘긴다. push-proxy는 원격 임시 디렉터리에 source tar를 풀고 Dockerized Go build로 ARM64 dist를 만든 뒤 `docker build --platform linux/arm64`로 image를 만든다.
|
||||
|
||||
수정 파일 및 체크리스트:
|
||||
- [ ] `bin/publish-runtime-images`를 추가하고 `bash -n`이 통과하게 한다.
|
||||
- [ ] `docs/runtime-image-validation.md`를 추가해 immutable tag, `latest` promotion, digest, remote command evidence 표를 둔다.
|
||||
- [ ] `docs/README.md` runtime index에 새 문서 링크를 추가한다.
|
||||
|
||||
테스트 작성: 자동 unit test는 작성하지 않는다. shell wrapper와 원격 Docker 동작은 명령 기반 smoke가 검증한다.
|
||||
|
||||
중간 검증:
|
||||
|
||||
```sh
|
||||
bash -n bin/publish-runtime-images
|
||||
rg --sort path -n "toki-labs.com:5050|linux/arm64|latest|digest" bin docs
|
||||
```
|
||||
|
||||
기대 결과: syntax error가 없고, registry/tag/architecture/evidence 문구가 새 wrapper와 문서에 나타난다.
|
||||
|
||||
### [IMG-2] Build Push Pull Evidence
|
||||
|
||||
문제: 원격 Docker는 동작하지만 현재 registry catalog에는 `nexo/mattermost`와 `nexo/push-proxy` image가 없다. upstream `mattermost/mattermost-team-edition:11.4.2` manifest는 amd64뿐이므로 Mac 전용 core image는 ARM64 package로 새로 만들어야 한다.
|
||||
|
||||
해결 방법: `bin/publish-runtime-images`를 실행해 immutable tag와 `latest`를 push한다. `latest`는 최신 빌드가 아니라 이 task에서 검증 통과한 stable pointer로만 promote한다. build 후 원격 Mac에서 pull, inspect, digest 기록을 수행하고 `docs/runtime-image-validation.md`에 결과를 남긴다.
|
||||
|
||||
수정 파일 및 체크리스트:
|
||||
- [ ] `docs/runtime-image-validation.md`에 core/push-proxy immutable tag, digest, `latest` digest, architecture evidence를 기록한다.
|
||||
- [ ] registry API catalog와 manifest inspect 결과를 `CODE_REVIEW-cloud-G07.md` 검증 결과에 붙인다.
|
||||
|
||||
테스트 작성: 별도 test file은 작성하지 않는다. 실제 registry push/pull과 Docker inspect가 acceptance test다.
|
||||
|
||||
중간 검증:
|
||||
|
||||
```sh
|
||||
curl -fsS https://toki-labs.com:5050/v2/_catalog
|
||||
ssh toki@toki-labs.com '/usr/local/bin/docker manifest inspect toki-labs.com:5050/nexo/mattermost:latest >/tmp/nexo-mm-latest.manifest.json && /usr/local/bin/docker manifest inspect toki-labs.com:5050/nexo/push-proxy:latest >/tmp/nexo-push-latest.manifest.json && grep -H "\"architecture\": \"arm64\"" /tmp/nexo-*-latest.manifest.json'
|
||||
```
|
||||
|
||||
기대 결과: catalog 조회가 성공하고 두 latest manifest가 `arm64` architecture를 포함한다.
|
||||
|
||||
## 수정 파일 요약
|
||||
|
||||
| 파일 | 항목 |
|
||||
|------|------|
|
||||
| `bin/publish-runtime-images` | IMG-1, IMG-2 |
|
||||
| `docs/runtime-image-validation.md` | IMG-1, IMG-2 |
|
||||
| `docs/README.md` | IMG-1 |
|
||||
|
||||
## 최종 검증
|
||||
|
||||
```sh
|
||||
bash -n bin/publish-runtime-images
|
||||
rg --sort path -n "toki-labs.com:5050|linux/arm64|latest|digest|nexo/mattermost|nexo/push-proxy" bin docs
|
||||
curl -fsS https://toki-labs.com:5050/v2/_catalog
|
||||
ssh toki@toki-labs.com '/usr/local/bin/docker manifest inspect toki-labs.com:5050/nexo/mattermost:latest >/tmp/nexo-mm-latest.manifest.json && /usr/local/bin/docker manifest inspect toki-labs.com:5050/nexo/push-proxy:latest >/tmp/nexo-push-latest.manifest.json && grep -H "\"architecture\": \"arm64\"" /tmp/nexo-*-latest.manifest.json'
|
||||
```
|
||||
|
||||
모든 명령은 fresh 실행이어야 하며 cached output은 허용하지 않는다. 모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
|
||||
137
bin/publish-runtime-images
Executable file
137
bin/publish-runtime-images
Executable file
|
|
@ -0,0 +1,137 @@
|
|||
#!/usr/bin/env bash
|
||||
# ====================================================================================
|
||||
# Nexo Runtime Image Publish Wrapper
|
||||
#
|
||||
# This script builds and publishes nexo-owned core (mattermost) and push-proxy images
|
||||
# for linux/arm64 architecture to the toki-labs.com:5050 registry.
|
||||
#
|
||||
# Since the local environment does not have docker installed, all docker build and
|
||||
# push operations are executed on the remote Mac build machine (toki@toki-labs.com)
|
||||
# using /usr/local/bin/docker.
|
||||
#
|
||||
# Stable tag 'latest' is only promoted after verifying the successfully pushed
|
||||
# immutable images.
|
||||
# ====================================================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Configurations
|
||||
REMOTE_HOST="toki@toki-labs.com"
|
||||
REGISTRY="toki-labs.com:5050"
|
||||
PLATFORM="linux/arm64"
|
||||
|
||||
# Set remote environment variables (specifically ensuring Docker Desktop helper binaries are in PATH)
|
||||
REMOTE_ENV="export PATH=\"/Applications/Docker.app/Contents/Resources/bin:/usr/local/bin:\$PATH\""
|
||||
|
||||
# Image Tags
|
||||
CORE_IMAGE_NAME="${REGISTRY}/nexo/mattermost"
|
||||
PUSH_PROXY_IMAGE_NAME="${REGISTRY}/nexo/push-proxy"
|
||||
IMMUTABLE_TAG="v11.4.2-arm64"
|
||||
|
||||
# Locate workspace root
|
||||
WORKSPACE_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
|
||||
echo "========================================================"
|
||||
echo "🚀 Starting Nexo Runtime Image Publish Wrapper (Stable Gate)"
|
||||
echo "========================================================"
|
||||
echo "Remote Host: ${REMOTE_HOST}"
|
||||
echo "Registry: ${REGISTRY}"
|
||||
echo "Architecture: ${PLATFORM}"
|
||||
echo "========================================================"
|
||||
|
||||
# ------------------------------------------------------------------------------------
|
||||
# 1. Build, Publish and Verify Core (Mattermost) Image
|
||||
# ------------------------------------------------------------------------------------
|
||||
echo "📦 [1/2] Processing Core (Mattermost) Image..."
|
||||
CORE_BUILD_DIR="/tmp/nexo-core-build"
|
||||
|
||||
echo "Creating remote directory for Core build..."
|
||||
ssh "${REMOTE_HOST}" "${REMOTE_ENV} && rm -rf ${CORE_BUILD_DIR} && mkdir -p ${CORE_BUILD_DIR}"
|
||||
|
||||
echo "Copying Core Dockerfile and passwd to remote..."
|
||||
scp "${WORKSPACE_ROOT}/services/core/server/build/Dockerfile" "${REMOTE_HOST}:${CORE_BUILD_DIR}/Dockerfile"
|
||||
scp "${WORKSPACE_ROOT}/services/core/server/build/passwd" "${REMOTE_HOST}:${CORE_BUILD_DIR}/passwd"
|
||||
|
||||
echo "Building Core Immutable Image on remote Mac..."
|
||||
ssh "${REMOTE_HOST}" "${REMOTE_ENV} && cd ${CORE_BUILD_DIR} && docker build --platform ${PLATFORM} \
|
||||
--build-arg MM_PACKAGE=\"https://releases.mattermost.com/11.4.2/mattermost-team-11.4.2-linux-arm64.tar.gz\" \
|
||||
-t ${CORE_IMAGE_NAME}:${IMMUTABLE_TAG} \
|
||||
."
|
||||
|
||||
echo "Pushing Core Immutable Image to registry..."
|
||||
ssh "${REMOTE_HOST}" "${REMOTE_ENV} && docker push ${CORE_IMAGE_NAME}:${IMMUTABLE_TAG}"
|
||||
|
||||
echo "Cleaning up Core build temporary files..."
|
||||
ssh "${REMOTE_HOST}" "${REMOTE_ENV} && rm -rf ${CORE_BUILD_DIR}"
|
||||
|
||||
echo "🔍 Verifying Core Immutable Image..."
|
||||
# Verify locally from the registry via exact Docker Registry V2 API path
|
||||
curl -fsSI -H "Accept: application/vnd.docker.distribution.manifest.v2+json" "https://${REGISTRY}/v2/nexo/mattermost/manifests/${IMMUTABLE_TAG}" > /dev/null
|
||||
# Verify remotely on the build host
|
||||
ssh "${REMOTE_HOST}" "${REMOTE_ENV} && docker image inspect ${CORE_IMAGE_NAME}:${IMMUTABLE_TAG} --format '{{.Os}}/{{.Architecture}}' | grep -q 'linux/arm64'"
|
||||
|
||||
echo "🎯 Promoting Core Immutable Image to stable 'latest'..."
|
||||
ssh "${REMOTE_HOST}" "${REMOTE_ENV} && docker tag ${CORE_IMAGE_NAME}:${IMMUTABLE_TAG} ${CORE_IMAGE_NAME}:latest && docker push ${CORE_IMAGE_NAME}:latest"
|
||||
echo "✅ Core (Mattermost) Image published and verified successfully!"
|
||||
echo ""
|
||||
|
||||
# ------------------------------------------------------------------------------------
|
||||
# 2. Build, Publish and Verify Push-Proxy Image
|
||||
# ------------------------------------------------------------------------------------
|
||||
echo "📦 [2/2] Processing Push-Proxy Image..."
|
||||
PUSH_PROXY_TAR="/tmp/push-proxy.tar.gz"
|
||||
PUSH_PROXY_BUILD_DIR="/tmp/push-proxy-build"
|
||||
|
||||
echo "Archiving Push-Proxy source files locally..."
|
||||
tar -czf "${PUSH_PROXY_TAR}" -C "${WORKSPACE_ROOT}/services/push-proxy" .
|
||||
|
||||
echo "Transferring Push-Proxy archive to remote..."
|
||||
scp "${PUSH_PROXY_TAR}" "${REMOTE_HOST}:/tmp/push-proxy.tar.gz"
|
||||
rm -f "${PUSH_PROXY_TAR}"
|
||||
|
||||
echo "Extracting Push-Proxy source on remote..."
|
||||
ssh "${REMOTE_HOST}" "${REMOTE_ENV} && rm -rf ${PUSH_PROXY_BUILD_DIR} && mkdir -p ${PUSH_PROXY_BUILD_DIR} && tar -xzf /tmp/push-proxy.tar.gz -C ${PUSH_PROXY_BUILD_DIR}"
|
||||
|
||||
echo "Running Manual Dockerized Go Build on remote Mac (avoids Makefile Git and Shell dependency issues)..."
|
||||
ssh "${REMOTE_HOST}" "${REMOTE_ENV} && cd ${PUSH_PROXY_BUILD_DIR} && docker run --rm \
|
||||
-v ${PUSH_PROXY_BUILD_DIR}:/app -w /app \
|
||||
golang:1.24.6-bookworm \
|
||||
/bin/sh -c \"mkdir -p /app/dist && CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -trimpath -ldflags '-X github.com/mattermost/mattermost-push-proxy/internal/version.gitVersion=v11.4.2-arm64' -o /app/dist/mattermost-push-proxy ./main.go\""
|
||||
|
||||
echo "Structuring and Packaging Push-Proxy software on remote Mac..."
|
||||
ssh "${REMOTE_HOST}" "${REMOTE_ENV} && cd ${PUSH_PROXY_BUILD_DIR} && \
|
||||
mkdir -p dist/mattermost-push-proxy-linux-arm64/bin && \
|
||||
mkdir -p dist/mattermost-push-proxy-linux-arm64/config && \
|
||||
mkdir -p dist/mattermost-push-proxy-linux-arm64/logs && \
|
||||
cp dist/mattermost-push-proxy dist/mattermost-push-proxy-linux-arm64/bin/mattermost-push-proxy && \
|
||||
cp -RL config/* dist/mattermost-push-proxy-linux-arm64/config/ && \
|
||||
cp LICENSE.txt NOTICE.txt README.md dist/mattermost-push-proxy-linux-arm64/ && \
|
||||
tar -czf dist/mattermost-push-proxy-linux-arm64.tar.gz -C dist mattermost-push-proxy-linux-arm64"
|
||||
|
||||
echo "Building Push-Proxy Immutable Image on remote Mac..."
|
||||
ssh "${REMOTE_HOST}" "${REMOTE_ENV} && cd ${PUSH_PROXY_BUILD_DIR} && docker build --platform ${PLATFORM} \
|
||||
--build-arg TARGETARCH=arm64 \
|
||||
-f docker/Dockerfile \
|
||||
-t ${PUSH_PROXY_IMAGE_NAME}:${IMMUTABLE_TAG} \
|
||||
."
|
||||
|
||||
echo "Pushing Push-Proxy Immutable Image to registry..."
|
||||
ssh "${REMOTE_HOST}" "${REMOTE_ENV} && docker push ${PUSH_PROXY_IMAGE_NAME}:${IMMUTABLE_TAG}"
|
||||
|
||||
echo "Cleaning up Push-Proxy build temporary files..."
|
||||
ssh "${REMOTE_HOST}" "${REMOTE_ENV} && rm -rf ${PUSH_PROXY_BUILD_DIR} && rm -f /tmp/push-proxy.tar.gz"
|
||||
|
||||
echo "🔍 Verifying Push-Proxy Immutable Image..."
|
||||
# Verify locally from the registry via exact Docker Registry V2 API path
|
||||
curl -fsSI -H "Accept: application/vnd.docker.distribution.manifest.v2+json" "https://${REGISTRY}/v2/nexo/push-proxy/manifests/${IMMUTABLE_TAG}" > /dev/null
|
||||
# Verify remotely on the build host
|
||||
ssh "${REMOTE_HOST}" "${REMOTE_ENV} && docker image inspect ${PUSH_PROXY_IMAGE_NAME}:${IMMUTABLE_TAG} --format '{{.Os}}/{{.Architecture}}' | grep -q 'linux/arm64'"
|
||||
|
||||
echo "🎯 Promoting Push-Proxy Immutable Image to stable 'latest'..."
|
||||
ssh "${REMOTE_HOST}" "${REMOTE_ENV} && docker tag ${PUSH_PROXY_IMAGE_NAME}:${IMMUTABLE_TAG} ${PUSH_PROXY_IMAGE_NAME}:latest && docker push ${PUSH_PROXY_IMAGE_NAME}:latest"
|
||||
echo "✅ Push-Proxy Image published and verified successfully!"
|
||||
echo ""
|
||||
|
||||
echo "========================================================"
|
||||
echo "🎉 All Nexo Runtime Images Verified and Published!"
|
||||
echo "========================================================"
|
||||
|
|
@ -13,3 +13,5 @@ Module-specific instructions stay with the module that owns them.
|
|||
- Core upstream snapshot baseline: `../services/core/UPSTREAM.md`
|
||||
- Mattermost mobile app upstream snapshot baseline: `../apps/mattermost/UPSTREAM.md`
|
||||
- Mattermost push-proxy upstream snapshot baseline: `../services/push-proxy/UPSTREAM.md`
|
||||
- Runtime Image Validation details: `runtime-image-validation.md`
|
||||
|
||||
|
|
|
|||
47
docs/runtime-image-validation.md
Normal file
47
docs/runtime-image-validation.md
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# Nexo Runtime Image Validation
|
||||
|
||||
This document records the registry, tag, architecture, and verification digests for nexo-owned runtime images.
|
||||
|
||||
## Published Images Summary
|
||||
|
||||
| Service | Target Architecture | Immutable Tag | Latest Tag | Digest (Immutable Tag) | Digest (Latest) |
|
||||
|---|---|---|---|---|---|
|
||||
| **Core (Mattermost)** | `linux/arm64` | `v11.4.2-arm64` | `latest` | `sha256:a811233f0625dd72a43c4b2315010ad67355fccc34be3e29d44e7aaab202b3ee` | `sha256:a811233f0625dd72a43c4b2315010ad67355fccc34be3e29d44e7aaab202b3ee` |
|
||||
| **Push-Proxy** | `linux/arm64` | `v11.4.2-arm64` | `latest` | `sha256:73d104148e66bb24e901bd1787624cf9b46e41268955e20bdfe4c6fc70f10b0b` | `sha256:73d104148e66bb24e901bd1787624cf9b46e41268955e20bdfe4c6fc70f10b0b` |
|
||||
|
||||
## Verification Evidence
|
||||
|
||||
### Registry API Manifest Headers
|
||||
This section displays registry manifest verification logs, ensuring the matching `Docker-Content-Digest` is resolved.
|
||||
|
||||
```sh
|
||||
# Fetch Core (Mattermost) manifests from registry
|
||||
$ curl -fsSI -H 'Accept: application/vnd.docker.distribution.manifest.v2+json' https://toki-labs.com:5050/v2/nexo/mattermost/manifests/latest
|
||||
HTTP/1.1 200 OK
|
||||
Server: nginx/1.29.3
|
||||
Content-Type: application/vnd.docker.distribution.manifest.v2+json
|
||||
Content-Length: 6766
|
||||
Docker-Content-Digest: sha256:a811233f0625dd72a43c4b2315010ad67355fccc34be3e29d44e7aaab202b3ee
|
||||
Etag: "sha256:a811233f0625dd72a43c4b2315010ad67355fccc34be3e29d44e7aaab202b3ee"
|
||||
|
||||
# Fetch Push-Proxy manifests from registry
|
||||
$ curl -fsSI -H 'Accept: application/vnd.docker.distribution.manifest.v2+json' https://toki-labs.com:5050/v2/nexo/push-proxy/manifests/latest
|
||||
HTTP/1.1 200 OK
|
||||
Server: nginx/1.29.3
|
||||
Content-Type: application/vnd.docker.distribution.manifest.v2+json
|
||||
Content-Length: 1577
|
||||
Docker-Content-Digest: sha256:73d104148e66bb24e901bd1787624cf9b46e41268955e20bdfe4c6fc70f10b0b
|
||||
Etag: "sha256:73d104148e66bb24e901bd1787624cf9b46e41268955e20bdfe4c6fc70f10b0b"
|
||||
```
|
||||
|
||||
### Remote Host Image Inspect (Architecture Proof)
|
||||
This section lists concrete inspection output executed directly on the remote Mac build host (`toki@toki-labs.com`).
|
||||
|
||||
```sh
|
||||
$ ssh toki@toki-labs.com '/usr/local/bin/docker image inspect toki-labs.com:5050/nexo/mattermost:latest --format "{{.Os}}/{{.Architecture}} {{range .RepoDigests}}{{.}} {{end}}" && /usr/local/bin/docker image inspect toki-labs.com:5050/nexo/mattermost:v11.4.2-arm64 --format "{{.Os}}/{{.Architecture}} {{range .RepoDigests}}{{.}} {{end}}" && /usr/local/bin/docker image inspect toki-labs.com:5050/nexo/push-proxy:latest --format "{{.Os}}/{{.Architecture}} {{range .RepoDigests}}{{.}} {{end}}" && /usr/local/bin/docker image inspect toki-labs.com:5050/nexo/push-proxy:v11.4.2-arm64 --format "{{.Os}}/{{.Architecture}} {{range .RepoDigests}}{{.}} {{end}}"'
|
||||
|
||||
linux/arm64 toki-labs.com:5050/nexo/mattermost@sha256:a811233f0625dd72a43c4b2315010ad67355fccc34be3e29d44e7aaab202b3ee
|
||||
linux/arm64 toki-labs.com:5050/nexo/mattermost@sha256:a811233f0625dd72a43c4b2315010ad67355fccc34be3e29d44e7aaab202b3ee
|
||||
linux/arm64 toki-labs.com:5050/nexo/push-proxy@sha256:73d104148e66bb24e901bd1787624cf9b46e41268955e20bdfe4c6fc70f10b0b
|
||||
linux/arm64 toki-labs.com:5050/nexo/push-proxy@sha256:73d104148e66bb24e901bd1787624cf9b46e41268955e20bdfe4c6fc70f10b0b
|
||||
```
|
||||
Loading…
Reference in a new issue