Merge commits from dest painted the network graph. Promote now moves the main ref when main has no unique patches.
151 lines
5.0 KiB
YAML
151 lines
5.0 KiB
YAML
name: Promote Dev to Main
|
|
|
|
# `dev` is the working branch. `main` is a pointer to the same history, moved
|
|
# only by this workflow. Merge commits from dev → main are what painted the
|
|
# GitHub network graph; this job moves the `main` ref to `dev` instead.
|
|
on:
|
|
push:
|
|
branches: [dev]
|
|
tags: ['chore.*']
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: promote-dev-to-main
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
decide:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
run: ${{ steps.check.outputs.run }}
|
|
reason: ${{ steps.check.outputs.reason }}
|
|
steps:
|
|
- name: Decide whether to promote
|
|
id: check
|
|
env:
|
|
EVENT_NAME: ${{ github.event_name }}
|
|
REF: ${{ github.ref }}
|
|
REF_TYPE: ${{ github.ref_type }}
|
|
HEAD_COMMIT_MSG: ${{ github.event.head_commit.message }}
|
|
run: |
|
|
set -euo pipefail
|
|
run='false'
|
|
reason=''
|
|
|
|
case "${EVENT_NAME}" in
|
|
workflow_dispatch)
|
|
run='true'
|
|
reason='Manual workflow_dispatch'
|
|
;;
|
|
push)
|
|
if [ "${REF_TYPE}" = 'tag' ]; then
|
|
run='true'
|
|
reason="Tag push: ${REF}"
|
|
elif [ "${REF}" = 'refs/heads/dev' ]; then
|
|
msg="${HEAD_COMMIT_MSG:-}"
|
|
if printf '%s' "${msg}" | grep -qiE '^\[merge\]|^chore\(release\):'; then
|
|
run='true'
|
|
reason='Commit message prefix on dev ([merge] or chore(release):)'
|
|
else
|
|
reason='Commit on dev without [merge] / chore(release): prefix'
|
|
fi
|
|
else
|
|
reason="Push event on unhandled ref: ${REF}"
|
|
fi
|
|
;;
|
|
*)
|
|
reason="Unhandled event: ${EVENT_NAME}"
|
|
;;
|
|
esac
|
|
|
|
{
|
|
echo "run=${run}"
|
|
echo "reason=${reason}"
|
|
} >> "${GITHUB_OUTPUT}"
|
|
|
|
{
|
|
echo "## Promote decision"
|
|
echo
|
|
echo "| Key | Value |"
|
|
echo "| --- | --- |"
|
|
echo "| Event | \`${EVENT_NAME}\` |"
|
|
echo "| Ref | \`${REF}\` |"
|
|
echo "| Run | \`${run}\` |"
|
|
echo "| Reason | ${reason} |"
|
|
} >> "${GITHUB_STEP_SUMMARY}"
|
|
|
|
promote:
|
|
needs: decide
|
|
if: needs.decide.outputs.run == 'true'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Validate GitHub App credentials
|
|
env:
|
|
APP_ID: ${{ secrets.SNOWLUMA_BOT_APP_ID }}
|
|
PRIVATE_KEY: ${{ secrets.SNOWLUMA_BOT_PRIVATE_KEY }}
|
|
run: |
|
|
if [ -z "${APP_ID}" ] || [ -z "${PRIVATE_KEY}" ]; then
|
|
echo 'Missing SNOWLUMA_BOT_APP_ID and/or SNOWLUMA_BOT_PRIVATE_KEY secrets.' >&2
|
|
echo 'Configure the same GitHub App used by the nnphook native PR flow.' >&2
|
|
exit 1
|
|
fi
|
|
|
|
- name: Mint GitHub App installation token
|
|
id: app-token
|
|
uses: actions/create-github-app-token@v2
|
|
with:
|
|
app-id: ${{ secrets.SNOWLUMA_BOT_APP_ID }}
|
|
private-key: ${{ secrets.SNOWLUMA_BOT_PRIVATE_KEY }}
|
|
owner: ${{ github.repository_owner }}
|
|
repositories: ${{ github.event.repository.name }}
|
|
|
|
- name: Checkout
|
|
uses: actions/checkout@v6
|
|
with:
|
|
ref: dev
|
|
fetch-depth: 0
|
|
token: ${{ steps.app-token.outputs.token }}
|
|
|
|
- name: Point main at dev
|
|
env:
|
|
REASON: ${{ needs.decide.outputs.reason }}
|
|
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
run: |
|
|
set -euo pipefail
|
|
git fetch origin dev main
|
|
dev_sha="$(git rev-parse origin/dev)"
|
|
main_sha="$(git rev-parse origin/main)"
|
|
dev_short="$(git rev-parse --short origin/dev)"
|
|
main_short="$(git rev-parse --short origin/main)"
|
|
|
|
if [ "${dev_sha}" = "${main_sha}" ]; then
|
|
echo "::notice::main already equals dev @ ${dev_short}; nothing to promote."
|
|
{
|
|
echo "main already equals dev @ ${dev_short}"
|
|
} >> "${GITHUB_STEP_SUMMARY}"
|
|
exit 0
|
|
fi
|
|
|
|
unique="$(git cherry origin/dev origin/main | awk '/^\+/ { print $2 }' || true)"
|
|
if [ -n "${unique}" ]; then
|
|
echo '::error::main has unique commits that dev does not. Cherry-pick them onto dev first.' >&2
|
|
git log --oneline --no-walk ${unique}
|
|
exit 1
|
|
fi
|
|
|
|
git push --force-with-lease="refs/heads/main:${main_sha}" origin "origin/dev:refs/heads/main"
|
|
echo "::notice::Updated main ${main_short} → dev@${dev_short}"
|
|
{
|
|
echo "## Promote"
|
|
echo
|
|
echo "| Key | Value |"
|
|
echo "| --- | --- |"
|
|
echo "| \`main\` was | \`${main_sha}\` |"
|
|
echo "| \`main\` now | \`dev\` @ \`${dev_sha}\` |"
|
|
echo "| Reason | ${REASON} |"
|
|
echo "| Workflow run | ${RUN_URL} |"
|
|
} >> "${GITHUB_STEP_SUMMARY}"
|