Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions .github/scripts/supply-chain-policy.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@ async function workflows() {
);
}

// 같은 저장소의 로컬 액션·reusable workflow 는 uses 대상이 이 저장소의 리비전이라
// 고정 대상이 아니다. 그 밖은 전부 40자리 commit SHA 여야 한다.
function isLocalReference(reference) {
return reference.startsWith("./");
}

function isPinnedToCommit(reference) {
return /@[0-9a-f]{40}$/.test(reference);
}

function actionReferences(source) {
return [...source.matchAll(/^\s*(?:-\s+)?uses:\s*(\S+)/gm)].map((match) => match[1]);
}

function requiresGradleSetup(source) {
return source.includes('./gradlew') || /uses:\s*gradle\/actions\/setup-gradle@/.test(source);
}
Expand All @@ -28,6 +42,65 @@ test('recognizes direct and script-delegated Gradle workflows', () => {
);
});

test('recognizes floating action references that the pinning policy must reject', () => {
// 정책이 실제로 무엇을 막는지 fixture 로 고정한다 — 태그·브랜치·짧은 SHA 는 전부
// 사후에 다른 코드로 바뀔 수 있다.
assert.equal(isPinnedToCommit('actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1'), true);
assert.equal(isPinnedToCommit('actions/checkout@v7'), false);
assert.equal(isPinnedToCommit('ScaCap/action-ktlint@master'), false);
assert.equal(isPinnedToCommit('actions/checkout@3d3c42e'), false);
assert.equal(isLocalReference('./.github/actions/setup-ci-config'), true);
assert.equal(isLocalReference('actions/checkout@v7'), false);
});

test('every third-party action is pinned to an immutable commit SHA', async () => {
const unpinned = [];
for (const [name, source] of await workflows()) {
for (const reference of actionReferences(source)) {
if (isLocalReference(reference) || isPinnedToCommit(reference)) {
continue;
}
unpinned.push(`${name}: ${reference}`);
}
}

assert.deepEqual(unpinned, []);
});

test('every pinned action records the release it was pinned from', async () => {
// SHA 만 있으면 무엇을 쓰고 있는지 사람이 읽을 수 없고 Dependabot 갱신도 대조가 안 된다.
const undocumented = [];
for (const [name, source] of await workflows()) {
for (const line of source.split('\n')) {
const match = /^\s*(?:-\s+)?uses:\s*(\S+@[0-9a-f]{40})(.*)$/.exec(line);
if (match && !/^\s*#\s*v?\d/.test(match[2])) {
undocumented.push(`${name}: ${match[1]}`);
}
}
}

assert.deepEqual(undocumented, []);
});

test('composite actions in this repository pin their own dependencies', async () => {
const directory = new URL('../actions/', import.meta.url);
const names = await readdir(directory);
for (const name of names) {
let source;
try {
source = await readFile(new URL(`${name}/action.yml`, directory), 'utf8');
} catch {
continue;
}
for (const reference of actionReferences(source)) {
assert.ok(
isLocalReference(reference) || isPinnedToCommit(reference),
`${name} uses an unpinned action: ${reference}`,
);
}
}
});

test('every workflow that runs the Gradle wrapper uses the pinned setup-gradle action', async () => {
const gradleWorkflows = (await workflows()).filter(([, source]) => requiresGradleSetup(source));
assert.ok(gradleWorkflows.length > 0);
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/android-managed-device.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ jobs:
timeout-minutes: 45
steps:
- name: Clone repo
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Set up JDK
uses: actions/setup-java@v5
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0
with:
distribution: temurin
java-version: "21"
Expand Down Expand Up @@ -54,7 +54,7 @@ jobs:

- name: Upload androidTest reports and failure evidence
if: always()
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: android-managed-device-results-${{ github.run_attempt }}
if-no-files-found: warn
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/auto-close-issue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Close issues referenced by close keywords
uses: actions/github-script@v9
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const pr = context.payload.pull_request;
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/conflict-label.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
timeout-minutes: 10
steps:
- name: Clone repo
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/dependency-audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ jobs:
REPORT_DIR: build/reports/dependency-audit
steps:
- name: Clone default branch
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Set up JDK 21
uses: actions/setup-java@v5
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0
with:
distribution: 'temurin'
java-version: '21'
Expand Down Expand Up @@ -124,7 +124,7 @@ jobs:

- name: Upload machine-readable audit evidence
if: always()
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: android-dependency-audit
path: ${{ env.REPORT_DIR }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/firebase-wif-canary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
steps:
# google-github-actions/auth가 ADC 파일을 안전하게 만들려면 checkout이 먼저 실행돼야 한다.
- name: Clone repo
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Prepare Firebase release notes
env:
Expand All @@ -81,7 +81,7 @@ jobs:
cat "$RELEASE_NOTES_FILE" >> "$GITHUB_STEP_SUMMARY"

- name: Set up JDK 21
uses: actions/setup-java@v5
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0
with:
distribution: temurin
java-version: '21'
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Clone repo
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Set up JDK 21
uses: actions/setup-java@v5
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0
with:
distribution: 'temurin'
java-version: '21'
Expand Down Expand Up @@ -58,10 +58,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Clone repo
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Set up JDK 21
uses: actions/setup-java@v5
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0
with:
distribution: 'temurin'
java-version: '21'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/mock-cleanup-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Clone repo
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Check for MOCK_CLEANUP markers
run: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release-distribution.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
# 이 job 은 release keystore·Firebase service account 를 받는다. 트리거가 push: [main] 하나여서
# ref 가 main 으로 고정되므로, 예전의 수동 실행용 브랜치 가드는 더 방어할 대상이 없어 제거했다.
- name: Clone repo
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Load release metadata from main PR
env:
Expand All @@ -57,7 +57,7 @@ jobs:
cat "$RELEASE_NOTES_FILE" >> "$GITHUB_STEP_SUMMARY"

- name: Set up JDK 21
uses: actions/setup-java@v5
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0
with:
distribution: 'temurin'
java-version: '21'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release-scope.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Clone release candidate
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.event.pull_request.head.sha || 'develop' }}
fetch-depth: 0
Expand All @@ -53,7 +53,7 @@ jobs:
"$RELEASE_SCOPE_PATH"

- name: Fill release sections on the PR body
uses: actions/github-script@v9
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
RELEASE_SCOPE_PATH: ${{ runner.temp }}/afternote-release-scope/scope.json
RELEASE_PR_NUMBER: ${{ github.event.pull_request.number || inputs.pull_request_number }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/repository-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
timeout-minutes: 3
steps:
- name: Clone repo
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Install actionlint
env:
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/screenshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Clone repo
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

# docker buildx + gha cache 로 Dockerfile.screenshot 빌드.
# 동일 이미지에서 baseline 생성·검증을 수행해 anti-aliasing/font/scale 등 host 환경 차이 root fix.
# Dockerfile 변경 없으면 cache 재사용 — 분당 단위 추가 비용.
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0

- name: Build screenshot image
uses: docker/build-push-action@v7
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: .
file: Dockerfile.screenshot
Expand Down Expand Up @@ -74,7 +74,7 @@ jobs:
# 실패 시 diff/rendered 이미지를 artifact 로 업로드 — 본인이 다운로드해 시각 차이 확인 가능
- name: Upload screenshot diff on failure
if: failure()
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: screenshot-test-results
path: |
Expand All @@ -89,7 +89,7 @@ jobs:
# 같은 PR 의 재실행에서는 기존 코멘트를 update (marker 로 중복 누적 방지).
- name: Comment artifact URL on PR (failure)
if: failure() && github.event_name == 'pull_request'
uses: actions/github-script@v9
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const marker = '<!-- screenshot-fail-bot -->';
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Clone repo
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Fetch pull request history for changed-module coverage
env:
Expand All @@ -42,7 +42,7 @@ jobs:
run: node --test .github/scripts/*.test.mjs

- name: Set up JDK 21
uses: actions/setup-java@v5
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0
with:
distribution: 'temurin'
java-version: '21'
Expand All @@ -62,7 +62,7 @@ jobs:

- name: Upload Kover coverage reports
id: kover-artifact
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: kover-jvm-coverage
path: build/reports/kover/
Expand All @@ -79,7 +79,7 @@ jobs:
# 실패한 테스트의 HTML/XML 리포트를 PR artifact 로 보존 — CI 로그에서 stack trace 추적이 빠름.
- name: Upload test reports on failure
if: failure()
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: unit-test-reports
path: |
Expand Down
Loading