머지 전 적용
더 많은 작업
apply-before-merge를 켜면 풀 리퀘스트의 실행이 직접 승인을 기다렸다가 적용하고 머지합니다. 그러면 기본 브랜치에는 적용된 것만 남습니다. 적용한 뒤 머지되지 않은 풀 리퀘스트가 있으면 프로덕션이 기본 브랜치보다 앞서게 되므로 merge 잡이 실패합니다. Atlantis와 digger가 쓰는 순서이고, 흔히 apply-before-merge라고 부릅니다.
다른 이름
- Terrateam은 두 순서를 pre-merge와 post-merge라고 부릅니다.
- Terramate와 Cloud Posse는 기본 순서를 apply-after-merge라고 부르고, Terramate는 merge-before-apply라고도 합니다.
- Atlantis의 이름을 따서 Atlantis식 워크플로라고도 합니다. Spacelift의 피드백 게시판이 그 예입니다.
require-up-to-date가 "true"가 아니면 베이스보다 뒤처진 풀 리퀘스트도 플랜하고 적용할 수 있습니다. 플랜은 머지 커밋에서 돌기 때문에, 베이스에서 같은 워크스페이스가 바뀌었으면 새 플랜이 달라져 적용이 멈추고, 다른 워크스페이스가 바뀐 것은 영향이 없습니다.
name: tofu
on:
pull_request:
workflow_dispatch:
inputs:
workspace:
description: The workspace to apply from this branch, once its environment approves.
required: true
type: choice
options: &workspaces [network, dns]
permissions: {}
jobs:
plan:
name: ${{ matrix.workspace }} plan
if: github.event_name == 'pull_request'
strategy:
fail-fast: false
matrix:
workspace: *workspaces
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: femiwiki/terraform-github-tacos@v0.7.0
with:
step: plan
workspace: ${{ matrix.workspace }}
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- uses: dflook/tofu-plan@c7416238983bdd94c5486fb856bb7358f2bcc935 # v3.1.0
id: plan
env:
GITHUB_TOKEN: ${{ github.token }}
with:
path: ${{ matrix.workspace }}
- uses: femiwiki/terraform-github-tacos@v0.7.0
with:
step: changes
workspace: ${{ matrix.workspace }}
changes: ${{ steps.plan.outputs.changes }}
plan-json: ${{ steps.plan.outputs.json_plan_path }}
plan-text: ${{ steps.plan.outputs.text_plan_path }}
- uses: femiwiki/terraform-github-tacos@v0.7.0
if: always()
with:
step: collapse
pending:
needs: plan
if: >-
!cancelled() && (github.event_name == 'workflow_dispatch'
|| (needs.plan.result == 'success' && github.event.pull_request.head.repo.full_name == github.repository))
runs-on: ubuntu-latest
permissions:
actions: write
checks: read
pull-requests: read
outputs:
workspaces: ${{ steps.pending.outputs.workspaces }}
steps:
- uses: femiwiki/terraform-github-tacos@v0.7.0
id: pending
with:
step: pending
apply-before-merge: "true"
workspaces: ${{ inputs.workspace && format('["{0}"]', inputs.workspace) || '' }}
apply:
name: ${{ matrix.workspace }} apply
needs: pending
if: needs.pending.outputs.workspaces != '[]'
strategy:
fail-fast: false
matrix:
workspace: ${{ fromJSON(needs.pending.outputs.workspaces) }}
runs-on: ubuntu-latest
environment: ${{ matrix.workspace }}
permissions:
actions: read
contents: read
pull-requests: write
steps:
- uses: femiwiki/terraform-github-tacos@v0.7.0
id: approver
with:
step: apply
workspace: ${{ matrix.workspace }}
apply-before-merge: "true"
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- uses: dflook/tofu-apply@e3e5dfc8f935d4b152c767801046f63abf8a77d3 # v3.1.0
id: apply
env:
GITHUB_TOKEN: ${{ github.token }}
with:
path: ${{ matrix.workspace }}
auto_approve: ${{ github.event_name == 'workflow_dispatch' }}
- uses: femiwiki/terraform-github-tacos@v0.7.0
if: always()
with:
step: result
workspace: ${{ matrix.workspace }}
outcome: ${{ steps.apply.outcome }}
plan-json: ${{ steps.apply.outputs.json_plan_path }}
plan-text: ${{ steps.apply.outputs.text_plan_path }}
approver: ${{ steps.approver.outputs.approver }}
# Make this the one required check
gate:
name: ${{ github.event_name == 'pull_request' && 'tofu gate' || 'tofu gate (pull requests only)' }}
needs: [plan, pending, apply]
if: always() && github.event_name == 'pull_request'
runs-on: ubuntu-latest
permissions: {}
steps:
- uses: femiwiki/terraform-github-tacos@v0.7.0
with:
step: gate
needs: ${{ toJSON(needs) }}
merge:
needs: [pending, apply, gate]
if: >-
!cancelled() && needs.gate.result == 'success'
&& (needs.apply.result == 'success' || needs.pending.outputs.workspaces == '[]')
runs-on: ubuntu-latest
permissions:
actions: read
contents: write
deployments: read
pull-requests: write
steps:
- uses: femiwiki/terraform-github-tacos@v0.7.0
with:
step: merge
apply-before-merge: "true"
쌓인 풀 리퀘스트
GitHub가 공개 미리보기로 내놓은 네이티브 스택에서는 풀 리퀘스트를 승인하는 것이 머지하는 것과 같은 결과를 냅니다. 맨 아래 풀 리퀘스트는 혼자 적용되고 머지됩니다. 그보다 위의 풀 리퀘스트는 아래 풀 리퀘스트를 모두 담은 자기 플랜을 적용하고 스택 전체를 머지합니다. 이때 그 플랜이 워크스페이스 둘 이상을 바꾸면 pending이 실패합니다. 워크스페이스별 적용은 나란히 돌아서, 한쪽이 아직 적용되지 않은 다른 쪽의 결과를 필요로 할 수 있기 때문입니다. 이런 스택은 아래부터 적용하세요. 가장 아래 풀 리퀘스트가 머지되면 GitHub가 다음 풀 리퀘스트의 대상을 기본 브랜치로 바꾸고, 다음 실행이 거기서부터 플랜합니다.
네이티브 스택에 속하지 않으면서 다른 풀 리퀘스트의 브랜치를 대상으로 하는 풀 리퀘스트는 적용되지 않습니다.