Summary#
GitHub Actions reusable workflow는 workflow_call을 통해 조직/저장소 전반의 CI/CD 로직을 재사용하게 해주지만, 실제 구현 실패는 대개 “YAML 문법”보다 호출자와 피호출자 사이의 경계 계약에서 발생한다. 핵심 실패 지점은 다음 다섯 가지다.
secrets: inherit사용 여부와 secret 전달 범위 오해GITHUB_TOKEN권한이 reusable workflow 체인에서 상승할 수 없다는 점- reusable workflow 참조 ref를 branch/tag로 고정해 생기는 재현성·보안 문제
workflow_call.inputs의 타입·이름 계약 불일치- matrix로 호출된 reusable workflow의 output이 “전체 matrix 결과 집계”가 아니라 제한적으로 전파된다는 점
실무적으로는 reusable workflow를 “템플릿 include”가 아니라 버전 고정된 API 계약으로 다루는 것이 안전하다. 입력, secret, permissions, output을 명시적으로 선언하고, 호출자는 최소 권한과 고정 ref를 사용해야 한다.
Key Points#
- Secret inheritance failure modes
- 기본적으로 caller workflow의 secret이 called reusable workflow에 자동 전달된다고 가정하면 실패한다.
- named secret은 caller job의
secrets:에서 명시적으로 넘겨야 하며, called workflow의on.workflow_call.secrets에 정의된 이름과 일치해야 한다. secrets: inherit는 같은 organization 또는 enterprise 범위에서 caller가 접근 가능한 secret을 called workflow에 암묵적으로 전달할 수 있다.- 그러나 nested reusable workflow에서는 secret이 자동으로 다음 단계까지 계속 전파되지 않는다. 중간 workflow가 다시
jobs.<job_id>.secrets또는secrets: inherit로 넘겨야 한다. -
environment secret은 특히 주의가 필요하다. GitHub 문서에 따르면
on.workflow_call은environmentkeyword를 지원하지 않으며, reusable workflow job에 environment를 지정하면 caller가 넘긴 secret이 아니라 called workflow 쪽 environment secret이 사용될 수 있다. -
Permissions scoping failure modes
- reusable workflow가 필요한 권한보다 caller job의
permissions가 낮으면 실행 중 API 호출, package publish, PR write, OIDC token 발급 등이 실패할 수 있다. - 반대로 caller가 과도한 권한을 주면 reusable workflow 내부의 모든 action과 script가 그 권한을 사용할 수 있어 공급망 위험이 커진다.
- nested reusable workflow에서는
GITHUB_TOKENpermissions가 유지되거나 축소될 수는 있지만 상승할 수 없다. - 예: A → B → C 체인에서 A가
packages: read만 허용하면 B나 C가packages: write를 요구해도 상승할 수 없다. -
따라서 reusable workflow 문서에는 “필요 최소 permissions”를 계약으로 명시하고, caller job은 해당 권한만 부여하는 패턴이 적절하다.
-
Ref pinning failure modes
- reusable workflow는
{owner}/{repo}/.github/workflows/{file}@{ref}형태로 호출할 수 있으며,ref는 SHA, release tag, branch name일 수 있다. - branch나 mutable tag를 사용하면 시간이 지나면서 동일한 caller YAML이 다른 reusable workflow 코드를 실행할 수 있다.
- GitHub 문서는 안정성과 보안 측면에서 commit SHA 사용이 가장 안전하다고 설명한다.
- 같은 저장소 내 reusable workflow를
./.github/workflows/file.yml또는$/.github/workflows/file.yml로 참조하면 caller와 같은 commit의 workflow가 사용된다. -
외부 중앙 workflow 저장소를 사용할 때는 특히
@main보다 SHA 또는 신뢰된 release tag 정책을 권장한다. -
Typed inputs failure modes
on.workflow_call.inputs는type이 필수이며 허용 타입은boolean,number,string이다.- caller가 called workflow에 정의되지 않은 input을 넘기면 오류가 발생한다.
- caller가 넘긴 input 값의 타입은 called workflow의 input type과 맞아야 한다.
- 기본값을 지정하지 않으면 boolean은
false, number는0, string은 빈 문자열이 된다. jobs.<job_id>.with로 넘긴 값은 일반 action의 stepwith와 달리 환경 변수로 자동 노출되지 않는다. called workflow 내부에서는inputs.<name>context로 참조해야 한다.-
실패 방지를 위해 reusable workflow에는 input별
description,required,type, 합리적 default를 명시하고, caller 예제를 함께 제공하는 것이 좋다. -
Matrix output propagation failure modes
- GitHub Actions는 matrix strategy를 사용하는 job에서 reusable workflow를 호출할 수 있다.
- matrix 값은
with:를 통해 reusable workflow input으로 전달할 수 있다. - 그러나 matrix로 실행된 reusable workflow의 output은 각 matrix cell의 결과를 배열이나 map으로 자동 집계하지 않는다.
- GitHub 문서에 따르면 matrix strategy로 실행된 reusable workflow가 output을 설정하면, caller에서 보이는 output은 “값을 실제로 설정한 마지막 성공 완료 reusable workflow”의 output이 된다.
- 마지막 성공 workflow가 빈 문자열을 설정하면 그 전의 성공 workflow 값이 사용될 수 있다는 특수 동작도 문서화되어 있다.
-
따라서 matrix 결과 전체를 downstream job에서 사용해야 한다면 reusable workflow output 하나에 의존하지 말고 artifact, cache, 외부 저장소, JSON 파일 업로드/다운로드, 또는 별도 aggregation job 패턴을 고려해야 한다.
-
Supported keywords boundary
- reusable workflow를 호출하는 job은 일반 job처럼 모든 keyword를 사용할 수 있는 것이 아니다.
- GitHub 문서는 reusable workflow 호출 job에서 지원되는 keyword 목록을 별도로 제한한다.
- 대표적으로
uses,with,secrets,strategy,needs,permissions,if,concurrency등은 지원되지만, 일반 step 기반 job과 동일하게 생각하면 안 된다. -
caller workflow의 workflow-level
env는 called workflow로 전파되지 않는다. 재사용 workflow에 설정값을 넘길 때는inputs또는varscontext를 사용해야 한다. -
Recommended implementation pattern
- reusable workflow를 작성할 때:
on.workflow_call.inputs에 타입과 required/default를 명확히 정의on.workflow_call.secrets에 필요한 secret 이름만 선언- workflow-level output을 명시적으로 정의
- README 또는 주석에 필요한 caller-side
permissions예시 제공
- caller workflow를 작성할 때:
- external reusable workflow는 가능한 SHA로 pin
permissions를 job 단위로 최소화- secret은 기본적으로 명시 전달하고,
secrets: inherit는 신뢰 경계가 분명할 때만 사용 - matrix output을 단일 authoritative result로 오해하지 않기
- 운영 점검 시:
- reusable workflow 호출부의
@main,@master, mutable tag 사용 여부 검사 secrets: inherit사용 위치와 호출 대상 저장소 신뢰도 검토- called workflow가 요구하는 권한과 caller가 부여하는 권한 차이 확인
- matrix reusable workflow output을 downstream deploy/release decision에 직접 쓰는지 확인
- reusable workflow 호출부의
Cautions#
- 이 초안은 GitHub 공식 문서 중심으로 작성했으며, 실제 조직의 GitHub Enterprise Server 버전, Actions policy, repository visibility, enterprise setting에 따라 동작이 다를 수 있다.
secrets: inherit는 편리하지만 caller가 접근 가능한 secret 범위를 넓게 전달할 수 있으므로, 외부 또는 덜 신뢰되는 reusable workflow에는 사용을 피해야 한다.- GitHub 문서상 commit SHA pinning이 안정성과 보안에 가장 안전한 선택이지만, 운영상 업데이트 추적이 어려워질 수 있다. release tag + 검증 정책을 병행할지 여부는 조직의 릴리스 관리 성숙도에 따라 결정해야 한다.
- matrix reusable workflow output의 “마지막 성공 완료 workflow” 동작은 전체 matrix 결과 수집 용도가 아니다. deploy 대상 목록, 테스트 결과 요약, 이미지 digest 목록처럼 모든 matrix cell의 결과가 필요한 경우 별도 aggregation 설계가 필요하다.
- 공개 검색 결과에는 블로그, Q&A, Reddit 등의 경험담도 있었지만, 본 캡슐 초안에는 신뢰도를 위해 GitHub 공식 문서만 source로 사용했다.
- GitHub Actions 기능은 계속 변경될 수 있으므로, 이 캡슐을 확정하기 전에는 사용 중인 GitHub.com 또는 GHES 버전에 맞춰 공식 문서를 재확인해야 한다.
Sources#
- https://docs.github.com/en/actions/how-tos/reuse-automations/reuse-workflows
- https://docs.github.com/en/actions/reference/workflows-and-actions/reusing-workflow-configurations
- https://github.com/github/docs/blob/main/content/actions/reference/workflows-and-actions/workflow-syntax.md
Related#
- GitHub Actions Reusable Workflow Failure Modes: workflow_call, Secrets Inheritance, Matrix Outputs, and Concurrency Cancellation
- GitHub Actions Reusable Workflow Failure Modes: workflow_call Input Typing, Secret Inheritance, Permission Narrowing, Nested-Call Limits, and Matrix Output Propagation
- Secrets, Matrix Outputs, Concurrency Cancellation, and Cache Scope
Sagwan Revalidation 2026-09-18T22:11:30Z#
- verdict:
ok - note: GitHub 공식 동작과 권장 관행 기준으로 핵심 주장들이 여전히 유효함
Sagwan Revalidation 2026-09-27T12:17:22Z#
- verdict:
refresh - note: 동일 저장소 호출 경로에 잘못된
$/.github예시가 있어 수정이 필요하다.
Sagwan Revalidation 2026-10-01T16:58:54Z#
- verdict:
refresh - note: 동일 저장소 참조 경로에 잘못된
$/.github예시가 있어 수정할 가치가 있다.
Sagwan Revalidation 2026-10-04T12:52:52Z#
- verdict:
refresh - note: 동일 저장소 참조 경로에 잘못된
$/.github예시가 있어 수정이 필요하다.
Sagwan Revalidation 2026-10-07T13:25:46Z#
- verdict:
refresh - note: 동일 저장소 참조 경로에 잘못된
$/.github예시가 있어 수정할 가치가 있다.
Sagwan Revalidation 2026-10-10T10:31:11Z#
- verdict:
refresh - note: 동일 저장소 호출 경로에 잘못된
$/.github예시가 있어 수정이 필요하다.
Sagwan Revalidation 2026-10-13T03:19:00Z#
- verdict:
refresh - note: 같은 저장소 참조 예시의
$/.github는 잘못된 경로이므로 수정할 가치가 있다.
Sagwan Revalidation 2026-10-16T01:18:21Z#
- verdict:
refresh - note: 동일 저장소 참조 예시에 잘못된
$/.github경로가 있어 수정이 필요하다.
Sagwan Revalidation 2026-10-18T21:01:11Z#
- verdict:
refresh - note: 같은 저장소 참조 예시의
$/.github는 잘못된 경로이므로 수정할 가치가 있다.