# Milestone: Jenkins 얇은 빌드와 artifact 다운로드

## 위치

- Roadmap: `agent-roadmap/ROADMAP.md`
- Phase: `agent-roadmap/phase/security-distribution/PHASE.md`

## 목표

OTO 없이 Jenkins job만 얇게 구성해 AppSok 인증 ZIP을 반복 빌드하고, Jenkins artifact 링크로 바로 다운로드할 수 있게 한다. Jenkins에는 빌드 지식을 최소한으로 두고, 현재 프로젝트의 기존 인증 빌드 스크립트를 실행하는 thin launcher 역할만 부여한다.

## 상태

[완료]

## 승격 조건

- 없음

## 구현 잠금

- 상태: 해제
- SDD: 불필요 - Jenkins thin job 설정, 문서화, 1회 smoke evidence로 닫히는 운영 작업이며 앱 API/proto/schema 계약을 바꾸지 않는다.
- 결정 필요: 아래 체크리스트
  - [x] Jenkins job 생성/갱신은 사용자 제공 Jenkins API credential을 사용한다. 원격 SOPS 저장과 Jenkins API 인증 확인을 완료했다.
  - [x] artifact 다운로드는 Jenkins 로그인 사용자에게만 허용한다. 별도 공개 다운로드 경로는 이번 마일스톤 범위에서 만들지 않는다.
  - [x] build trigger는 `develop` branch에서 평소 개발 빌드를 수행하고, `develop`에서 `main`으로 merge될 때 Jenkins 인증 ZIP 빌드를 자동 실행한다. 자동 실행은 `main` branch filter가 걸린 Git push webhook 기준으로 두고 polling은 제외한다.
  - [x] Jenkins job 이름은 `appsok-macos-certified`로 하고, build log와 archived artifact는 최근 10개 build 기준으로 보관한다.

## 범위

- AppSok 전용 Jenkins job 생성 또는 갱신
- `macbook-ultra` Jenkins node에서 기존 인증 빌드 스크립트 실행
- 최종 ZIP과 checksum을 Jenkins archived artifact로 노출
- 최신 성공 빌드 artifact 다운로드 URL 확인
- Jenkins credential/API token을 tracked 파일에 남기지 않는 운영 절차

## 기능

### Epic: [job] Jenkins thin job

Jenkins job은 AppSok 빌드 스크립트를 호출하고 artifact를 보관하는 얇은 launcher로 유지한다.

- [x] [job-config] `macbook-ultra` node, AppSok SCM, `main` branch, shell build step을 포함한 Jenkins job config를 만든다.
- [x] [script-call] job build step이 `./scripts/build-certified-macos.sh`를 호출하고 secret 원문을 job config나 repository에 남기지 않는다.
- [x] [artifact-copy] `AppSok-certified.zip`과 `sha256` 값을 Jenkins workspace의 archive 대상 경로로 모은다.
- [x] [archive] Jenkins archived artifact 설정으로 ZIP과 checksum을 보관한다.
- [x] [retention] build log와 artifact 보관 정책을 최근 10개 build 기준에 맞춘다.

### Epic: [access] 빌드 실행과 다운로드 확인

사용자가 Jenkins에서 빌드를 실행하고 최신 성공 artifact를 확인할 수 있게 한다.

- [x] [trigger] 1차 trigger 방식을 적용한다.
- [x] [download-url] `lastSuccessfulBuild/artifact/.../AppSok-certified.zip` 다운로드 URL을 확인하고 문서화한다.
- [x] [auth-policy] Jenkins artifact 다운로드 권한 정책을 결정 사항에 맞게 반영한다.
- [x] [smoke] Jenkins build를 1회 실행하고 archived ZIP과 checksum을 다운로드 가능한 상태로 검증한다. 검증: Jenkins 최신 성공 빌드의 artifact URL이 인증된 사용자 기준으로 ZIP 응답을 반환한다.

## 완료 리뷰

- 상태: 승인됨
- 요청일: 2026-06-17
- 완료 근거: Jenkins job 설정 apply가 성공했고, Jenkins build #2가 SUCCESS로 종료되었다. 최신 성공 빌드의 `AppSok-certified.zip`과 `.sha256` artifact가 인증 사용자 기준 HTTP 200으로 다운로드되었고 ZIP size는 24,326,080 bytes, sha256은 `557339ba024afaedc614a5a5d88716a5d7daa4882c88903155e3318cc6363104`로 확인되었다.
- 리뷰 필요:
  - [x] 사용자가 완료 결과를 확인했다
  - [x] archive 이동을 승인했다
- 리뷰 코멘트: 사용자가 빌드 자체 정상 확인을 완료했고, 기능적인 부분은 추후 확인하기로 했다.

## 범위 제외

- OTO runner 또는 OTO Server를 Jenkins 대체 실행 주체로 도입하는 작업
- workspace 공통 Jenkins 가이드 또는 별도 agent skill 작성
- Jenkins plugin, Auth Broker, 중앙 감사 서버 구현
- 공용 Jenkins API token을 앱이나 repository에 내장하는 방식
- AppSok 앱 코드에서 Jenkins artifact 소비 흐름을 변경하는 작업

## 작업 컨텍스트

- 관련 경로: `scripts/build-certified-macos.sh`, `docs/macos-certified-build.md`, `agent-roadmap/phase/security-distribution/`
- 표준선(선택): Jenkins는 1차로 thin launcher와 artifact archive만 담당하고, 빌드 절차의 source of truth는 AppSok repository의 스크립트와 문서에 둔다.
- 표준선(선택): Jenkins API token, SSH credential, Apple credential, Keychain password 원문은 tracked 파일, task log, 최종 응답에 기록하지 않는다.
- 진행 현황: `trigger`, `download-url`, `auth-policy`는 Jenkins job XML dry-run, XML parse, 문서화, 스크립트 테스트, `flutter analyze`, `flutter test` evidence로 반영했다.
- 진행 현황: `smoke`는 Jenkins job apply, build #2 SUCCESS, 인증 사용자 기준 ZIP/checksum HTTP 200 응답으로 반영했다.
- 선행 작업: macOS 빌드 CI와 인증 빌드
- 후속 작업: macOS 배포와 sandbox 검증, 향후 OTO 기반 CI/CD 마이그레이션 후보
- 확인 필요: 없음
