Skip to content

security(ci): main Actions 참조를 SHA로 고정한다 [base: main] - #1273

Merged
1hyok merged 5 commits into
mainfrom
feat/847
Aug 27, 2026
Merged

1hyok merged 5 commits into
mainfrom
feat/847

Conversation

@1hyok

@1hyok 1hyok commented Aug 27, 2026 •

Copy link
Copy Markdown
Collaborator

Refs #847
Refs #1063

왜 필요한가

저장소의 sha_pinning_required는 특정 브랜치가 아니라 저장소 전체에 적용된다. develop은 이미 외부 Action을 전부 고정했지만, main에는 12개 워크플로의 부동 참조 30개가 남아 있었다. 이 상태에서 정책을 켜면 main push 기반 Firebase 릴리스가 시작 단계에서 차단된다.

변경

  • 12개 워크플로의 외부 uses: 30건을 40자리 commit SHA로 고정한다.
  • actions/upload-artifact의 v4/v7을 포함해 기존 Action major와 워크플로 동작은 유지한다.
  • 각 SHA 옆에 검증한 release tag를 주석으로 남긴다.
  • main push도 기존 correlator로 신뢰된 Gradle dependency snapshot을 제출해 이후 main PR의 base 비교가 비지 않게 한다.
  • Managed Device runner가 /dev/kvm 소유권·읽기·쓰기를 직접 검증하도록 develop의 KVM 설정을 backport한다.
  • main의 오래된 계측 fixture 네 곳을 현재 테스트 계약에 맞춘다: receiver saved-state key, daily/diary 초기 조회 횟수, memory month filtering.
  • Android 앱 런타임 코드, 리소스, 빌드 설정은 변경하지 않는다.
Action 고정 release
actions/checkout v7.0.1
actions/setup-java v5.7.0
actions/upload-artifact v4.6.2 / v7.0.1
actions/github-script v9.0.0
docker/setup-buildx-action v4.3.0
docker/build-push-action v7.3.0
dvdandroid/action-android-lint v1.3

검증

  • 외부 Action 참조 56건: 미고정 0건, release 주석 누락 0건
  • scripts/repository-quality.sh: 18 workflows, 4 shell scripts 통과
  • node --test .github/scripts/*.test.mjs: 98/98 통과
  • Ruby YAML parse: 18 workflows 통과
  • git diff --check: 통과
  • ./gradlew :app:compileDebugAndroidTestKotlin ktlintCheck: 617 tasks 통과
  • exact HEAD 199598ee1a506bc3e3a3b0f7bed0c176eebfb5af의 Managed Device run 33065369934: JUnit XML 81 tests, failures 0, errors 0, skipped 0
  • Action pin 변경은 uses: 참조 30줄로 한정하고, dependency-submission 변경은 develop에서 검증된 PR #1182의 main push 트리거와 job 명칭을 재사용한다.

🧪 QA Metadata

{
  "scope": "ci-only",
  "exclusionReason": "외부 GitHub Actions 참조, Managed Device runner 설정과 계측 fixture만 변경하며 앱 런타임 코드와 사용자 동작 경계는 변경하지 않습니다.",
  "androidTest": {
    "required": false,
    "reason": "앱 런타임 입력·화면·저장소 호출은 변경하지 않으며, workflow와 계측 fixture가 실제 기기 suite를 온전히 실행하는지는 exact-HEAD Managed Device 81/81 성공으로 검증합니다."
  },
  "evidence": [
    {
      "kind": "test",
      "ref": "repository-quality and immutable uses inventory",
      "assertion": "전체 workflow 정적 검증이 통과하고 외부 uses의 부동 참조가 0건이며 main push가 기존 correlator로 dependency snapshot을 제출합니다.",
      "input": "origin/main의 12개 workflow에 남은 외부 uses 30건과 main dependency base snapshot 누락",
      "boundary": ".github/workflows와 .github/actions의 모든 외부 uses 참조 및 dependency-submission push 트리거",
      "observation": "actionlint, shellcheck, node 정책 테스트가 통과하고 미고정 참조가 0건이며 workflow YAML 파싱이 통과했습니다."
    },
    {
      "kind": "test",
      "ref": "Android Managed Device run 33065369934",
      "assertion": "KVM 설정과 main 계측 fixture가 exact PR HEAD의 전체 API 30 suite를 실패·오류·스킵 없이 실행합니다.",
      "input": "PR HEAD 199598ee1a506bc3e3a3b0f7bed0c176eebfb5af와 pixel2Api30DebugAndroidTest",
      "boundary": "GitHub-hosted runner의 /dev/kvm, Android emulator, app androidTest JUnit 결과",
      "observation": "artifact JUnit XML에 tests=81, failures=0, errors=0, skipped=0이 기록됐습니다."
    }
  ]
}

포함 이슈

QA 포인트

  • main 기준 모든 외부 Action 참조가 40자리 commit SHA와 release 주석을 가진다.
  • release-distribution.yml의 checkout·setup-java가 고정 SHA로 실행되고 기존 Firebase 릴리스 로직은 변하지 않는다.
  • main push가 afternote-gradle-dependency-graph correlator로 base snapshot을 제출한다.
  • Managed Device API 30 전체 suite가 exact PR HEAD에서 81/81 통과한다.
  • 이 PR 머지 후 저장소 sha_pinning_required=true를 다시 적용하고 재조회한다.

릴리스 경계

이 PR은 main 대상이다. 머지하면 main push에 의해 Firebase App Distribution 릴리스가 실행되므로, 이번 작업에서는 PR 생성과 CI 확인까지만 수행하고 머지는 별도 승인 대상으로 둔다.

@1hyok
1hyok marked this pull request as ready for review August 27, 2026 12:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

android-test PR head에서 Android Managed Device 계측 테스트 실행

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants