개발/백엔드

🔒 GitHub Actions lockfile 2026 · actions.lock 언제 쓰나

개발만빼고다잘함 2026. 10. 29. 12:40
반응형

2026년 10월 28일 GitHub changelog에 워크플로 lockfile 정식 출시(GA) 글이 올라왔다. 대상은 GitHub Enterprise Cloud(데이터 레지던시 포함)·Team·Free 플랜이다.

워크플로에 actions/checkout@v6처럼 태그를 적어 두고 늘 찜찜했던 사람이 많을 것이다. 태그는 움직일 수 있다. 그렇다고 줄마다 커밋 SHA를 박자니 읽을 수가 없다.

먼저 알아둘 한계

lockfile이 잠그지 않는 범위부터 본다. 공식 문서에 적힌 내용이다.

  • 재사용 워크플로 호출 : jobs.<job_id>.uses는 잠그지 않는다. 전체 커밋 SHA로 참조하라고 안내한다
  • 다른 빌드 입력 : 입력 파라미터, 시크릿, 러너 이미지는 통제하지 않는다
  • 로컬 경로 액션 : uses: ./…는 따라가지도 잠그지도 않는다

changelog도 의존성이 안전한지는 판단하지 않는다고 적었다. 리뷰는 여전히 우리 몫이다.

만드는 명령

GitHub CLI 확장으로 만든다. 공식 문서 명령이다.

# 확장 설치
gh extension install github/gh-actions-lock

# 저장소 루트에서 인자 없이: .github/workflows/ 전체를 훑어 lockfile 작성
gh actions-lock

# 워크플로 하나만 온보딩
gh actions-lock .github/workflows/ci.yml

결과 파일은 .github/workflows/actions.lock이다. 손으로 고치지 말라고 문서가 못 박았다.

actions.lock 안에 적히는 것

workflows 절은 워크플로별 의존성 목록이다. dependencies 절은 각 참조가 풀린 커밋을 담는다.

공식 예시에 주석을 붙이면 이렇다.

version: 'v0.0.3'
workflows:
  '.github/workflows/ci.yml':        # 온보딩된 워크플로
    - 'octo-org/deploy-action@v3.1.0'
dependencies:
  'octo-org/deploy-action@v3.1.0':
    ref: 'v3.1.0'          # 커밋을 찾아낸 태그나 브랜치
    commit: 'sha1-...'     # 실제로 돌아갈 커밋
    owner_id: 44036562     # 소스 저장소의 숫자 ID
    repo_id: 197814629

owner_id와 repo_id는 실행 때 그 이름이 가리키는 저장소가 잠근 그 저장소인지 확인하는 값이다. 이 값이 바뀌면 머지 전에 조사하자.

SHA 고정과 차이

GitHub는 그동안 서드파티 액션을 전체 커밋 SHA로 고정하라고 권해 왔다. 개념 문서는 lockfile을 채택한 저장소라면 워크플로 파일 안 SHA 고정이 더는 필요 없다고 적었다. 다만 앞서 본 재사용 워크플로 호출은 여전히 SHA로 참조해야 한다.

비교워크플로에 SHA 고정actions.lock
비교 워크플로에 SHA 고정 actions.lock
워크플로 파일 해시가 그대로 보인다 태그·브랜치 유지
전이 의존성 못 잡는다 함께 잠근다
저장소 신원 기록 없음 owner_id·repo_id

SHA 고정이 메뉴판 이름마다 바코드를 붙이는 방식이라면 lockfile은 메뉴판은 두고 납품서를 따로 보관하는 쪽이다. 새 저장소라면 웬만하면 lockfile을 권한다.

켜면 달라지는 것

온보딩한 워크플로는 쓰는 액션이 전부 lockfile에 있어야 한다. 실행되는 건 잠긴 커밋이다. 포크에만 있거나 기록된 브랜치·태그에서 더는 닿지 않는 커밋은 거부된다.

확장은 워크플로의 uses 줄도 풀린 버전으로 바꾼다. 가리키는 커밋은 같다.

# 전: 부분 버전 태그
- uses: octo-org/deploy-action@v3
# 후: 확장이 구체 버전으로 고쳐 둔다
- uses: octo-org/deploy-action@v3.1.0

커밋 전에 diff를 보자. 함정은 허용 목록이다. 지정한 액션만 허용하는 허용 목록을 쓴다면 온보딩 뒤엔 태그가 아니라 잠긴 SHA로 검사한다. actions/checkout@v6 같은 태그 항목은 더는 안 맞는다. 와일드카드나 전체 커밋 SHA로 바꾸면 된다.

Dependabot은 온보딩된 워크플로의 액션 버전 PR에서 lockfile 항목도 같이 고친다.

Require lockfile 정책

관리자는 이 정책으로 채택을 강제할 수 있다. 온보딩 안 된 대상 워크플로는 uses:가 하나도 없어도 실행이 막힌다. 부른 재사용 워크플로가 자기 저장소에서 온보딩 안 됐어도 막힌다.

처음엔 막막할 텐데 문서도 Evaluate 모드로 Policy insights를 본 뒤 Active로 올리라고 권한다. Evaluate 모드는 Enterprise Cloud에서만 된다. changelog는 Free·Team까지 GA라 했지만 문서 상단 "Who can use" 칸에는 Enterprise Cloud만 적혀 있다는 점도 알아 두자.

CI에서 낡은 lockfile 잡기

PR 단계에서 미리 알려면 gh actions-lock --verify를 필수 체크로 돌린다. 공식 저장소 예시를 줄였다.

on:
  pull_request:
permissions:
  contents: read  # 검증만 하니 읽기 권한
jobs:
  verify:
    runs-on: ubuntu-latest
    env:
      GH_TOKEN: ${{ github.token }}
    steps:
      - uses: actions/checkout@v7.0.1
        with:
          persist-credentials: false
      - run: gh extension install github/gh-actions-lock --pin v0.2.0  # 확장 버전 고정
      - run: gh actions-lock --verify  # lockfile이 낡았으면 실패

여기에 actions.lock을 CODEOWNERS에 넣고 코드 오너 승인을 걸면 문서가 말하는 리뷰 절차까지 갖춰진다. 보안 업데이트 해당 조건을 따진 글은 Next.js 16.4.1 보안 업데이트 글에 따로 적어 뒀다.

참고

반응형