name: Promote Dev Image by Pull Request on: workflow_dispatch: inputs: service: description: Workload to promote required: true type: choice options: - auth-server - api-server image_digest: description: Immutable OCI digest including the sha256 prefix required: true type: string concurrency: group: promote-dev-${{ inputs.service }} cancel-in-progress: false jobs: promote: runs-on: - self-hosted - linux steps: - name: Checkout uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 token: ${{ secrets.GITOPS_BOT_TOKEN }} - name: Update immutable digest env: SERVICE: ${{ inputs.service }} IMAGE_DIGEST: ${{ inputs.image_digest }} run: | case "$SERVICE" in auth-server) image_name="ghcr.io/donghyeonka/project-auth-server" ;; api-server) image_name="ghcr.io/donghyeonka/project-api-server" ;; *) echo "Unsupported service: $SERVICE" >&2 exit 1 ;; esac if [[ ! "$IMAGE_DIGEST" =~ ^sha256:[a-f0-9]{64}$ ]]; then echo "image_digest must be an immutable sha256 digest" >&2 exit 1 fi manifest="clusters/dev-k3s/overlays/workloads/${SERVICE}/kustomization.yaml" temporary="$(mktemp "${manifest}.XXXXXX")" awk -v image_name="$image_name" -v image_digest="$IMAGE_DIGEST" ' $1 == "-" && $2 == "name:" { target = ($3 == image_name) } target && $1 == "newTag:" { match($0, /^[[:space:]]*/) print substr($0, RSTART, RLENGTH) "digest: " image_digest target = 0 updated = 1 next } target && $1 == "digest:" { match($0, /^[[:space:]]*/) print substr($0, RSTART, RLENGTH) "digest: " image_digest target = 0 updated = 1 next } { print } END { if (!updated) exit 42 } ' "$manifest" >"$temporary" mv "$temporary" "$manifest" kubectl kustomize "$(dirname "$manifest")" >/dev/null - name: Create promotion branch env: SERVICE: ${{ inputs.service }} RUN_NUMBER: ${{ gitea.run_number }} run: | branch="gitops/promote-${SERVICE}-${RUN_NUMBER}" git config user.name "gitops-bot" git config user.email "gitops-bot@hyeonworks.local" git switch -c "$branch" git add "clusters/dev-k3s/overlays/workloads/${SERVICE}/kustomization.yaml" git commit -m "chore(gitops): promote ${SERVICE} dev digest" git push --set-upstream origin "$branch" echo "PROMOTION_BRANCH=$branch" >>"$GITHUB_ENV" - name: Open Gitea pull request env: GITEA_TOKEN: ${{ secrets.GITOPS_BOT_TOKEN }} GITEA_API_URL: ${{ gitea.api_url }} REPOSITORY: ${{ gitea.repository }} DEFAULT_BRANCH: ${{ gitea.event.repository.default_branch }} SERVICE: ${{ inputs.service }} IMAGE_DIGEST: ${{ inputs.image_digest }} run: | payload="$( jq -n \ --arg base "$DEFAULT_BRANCH" \ --arg head "$PROMOTION_BRANCH" \ --arg title "chore(gitops): promote ${SERVICE} dev digest" \ --arg body "Promotes ${SERVICE} to immutable digest ${IMAGE_DIGEST}." \ '{base: $base, head: $head, title: $title, body: $body}' )" curl -fsS \ -H "Authorization: token ${GITEA_TOKEN}" \ -H "Content-Type: application/json" \ -d "$payload" \ "${GITEA_API_URL}/repos/${REPOSITORY}/pulls"