Skip to content

[ci] Auto-resolve predictable PR conflicts #324

[ci] Auto-resolve predictable PR conflicts

[ci] Auto-resolve predictable PR conflicts #324

Workflow file for this run

name: Changelog Automation
on:
workflow_call:
inputs:
changelog-file:
description: Path to the managed changelog file.
required: false
type: string
default: CHANGELOG.md
project:
description: Optional GitHub Project V2 number for consumer repositories. When omitted, php-fast-forward repositories default to the first organization project.
required: false
type: string
default: ''
version:
description: Optional version to promote during manual release preparation.
required: false
type: string
default: ''
release-branch-prefix:
description: Prefix used for release-preparation branches.
required: false
type: string
default: release/v
workflow_dispatch:
inputs:
changelog-file:
description: Path to the managed changelog file.
required: false
type: string
default: CHANGELOG.md
project:
description: Optional GitHub Project V2 number for consumer repositories. Leave empty to use the configured repository variable or the php-fast-forward default.
required: false
type: string
default: ''
version:
description: Optional version to promote. Leave empty to infer from Unreleased.
required: false
type: string
default: ''
release-branch-prefix:
description: Prefix used for release-preparation branches.
required: false
type: string
default: release/v
pull_request:
types: [opened, reopened, synchronize]
pull_request_target:
types: [closed]
permissions:
contents: write
pull-requests: write
repository-projects: write
concurrency:
group: ${{ github.event.pull_request.number && format('changelog-pr-{0}', github.event.pull_request.number) || format('changelog-{0}', github.ref) }}
cancel-in-progress: ${{ github.event.pull_request.merged != true }}
env:
FORCE_COLOR: '1'
jobs:
resolve_php:
name: Resolve PHP Version
runs-on: ubuntu-latest
outputs:
php-version: ${{ steps.resolve.outputs.php-version }}
steps:
- uses: actions/checkout@v6
- name: Checkout dev-tools workflow action source
uses: actions/checkout@v6
with:
repository: php-fast-forward/dev-tools
ref: ${{ github.repository == 'php-fast-forward/dev-tools' && (github.event_name == 'pull_request_target' && github.event.pull_request.base.sha || github.sha) || 'main' }}
path: .dev-tools-actions
sparse-checkout: |
.github/actions
- name: Resolve workflow PHP version
id: resolve
uses: ./.dev-tools-actions/.github/actions/php/resolve-version
validate_pull_request:
name: Validate PR Changelog
needs: resolve_php
if: ${{ github.event.pull_request.number && github.event.pull_request.merged != true && !startsWith(github.event.pull_request.head.ref, inputs.release-branch-prefix || 'release/v') }}
runs-on: ubuntu-latest
env:
CHANGELOG_FILE: ${{ inputs.changelog-file || 'CHANGELOG.md' }}
CHANGELOG_ROOT_VERSION: ${{ github.event.pull_request.head.ref && format('dev-{0}', github.event.pull_request.head.ref) || 'dev-main' }}
BASE_REF: ${{ github.event.pull_request.base.ref }}
HEAD_REF: ${{ github.event.pull_request.head.ref }}
PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
PULL_REQUEST_TITLE: ${{ github.event.pull_request.title }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Checkout dev-tools workflow action source
uses: actions/checkout@v6
with:
repository: php-fast-forward/dev-tools
ref: ${{ github.repository == 'php-fast-forward/dev-tools' && (github.event_name == 'pull_request_target' && github.event.pull_request.base.sha || github.sha) || 'main' }}
path: .dev-tools-actions
sparse-checkout: |
.github/actions
- name: Setup PHP and install dependencies
uses: ./.dev-tools-actions/.github/actions/php/setup-composer
with:
php-version: ${{ needs.resolve_php.outputs.php-version }}
root-version: ${{ env.CHANGELOG_ROOT_VERSION }}
install-options: --prefer-dist --no-progress --no-interaction --no-plugins --no-scripts
- name: Fetch base branch reference
run: git fetch --no-tags --depth=1 origin "+refs/heads/${BASE_REF}:refs/remotes/origin/${BASE_REF}"
- name: Create Dependabot changelog entry when missing
id: dependabot_entry
if: ${{ (github.event.pull_request.user.login == 'dependabot[bot]' || github.event.pull_request.user.login == 'app/dependabot' || startsWith(github.event.pull_request.head.ref, 'dependabot/')) && github.event.pull_request.head.repo.full_name == github.repository }}
uses: ./.dev-tools-actions/.github/actions/changelog/create-dependabot-entry
with:
changelog-file: ${{ env.CHANGELOG_FILE }}
base-ref: ${{ env.BASE_REF }}
head-ref: ${{ env.HEAD_REF }}
pull-request-number: ${{ env.PULL_REQUEST_NUMBER }}
pull-request-title: ${{ env.PULL_REQUEST_TITLE }}
- name: Verify changelog update
run: composer dev-tools changelog:check -- --file="${CHANGELOG_FILE}" --against="origin/${BASE_REF}"
- uses: ./.dev-tools-actions/.github/actions/summary/write
with:
markdown: |
## Changelog Validation Summary
- Changelog file: `${{ env.CHANGELOG_FILE }}`
- Compared base ref: `origin/${{ env.BASE_REF }}`
- Dependabot fallback status: `${{ steps.dependabot_entry.outputs.status || 'not needed' }}`
- Dependabot fallback entry created: `${{ steps.dependabot_entry.outputs.created || 'false' }}`
- Dependabot fallback generated message: `${{ steps.dependabot_entry.outputs.message || 'not needed' }}`
- Validation result: success
prepare_release_pull_request:
name: Prepare Release Pull Request
needs: resolve_php
if: ${{ !github.event.pull_request.number }}
runs-on: ubuntu-latest
env:
CHANGELOG_FILE: ${{ inputs.changelog-file || 'CHANGELOG.md' }}
RELEASE_BRANCH_PREFIX: ${{ inputs.release-branch-prefix || 'release/v' }}
CHANGELOG_ROOT_VERSION: ${{ format('dev-{0}', github.event.repository.default_branch) }}
steps:
- uses: actions/checkout@v6
with:
token: ${{ github.token }}
ref: ${{ github.event.repository.default_branch }}
fetch-depth: 0
- name: Checkout dev-tools workflow action source
uses: actions/checkout@v6
with:
repository: php-fast-forward/dev-tools
ref: ${{ github.repository == 'php-fast-forward/dev-tools' && (github.event_name == 'pull_request_target' && github.event.pull_request.base.sha || github.sha) || 'main' }}
path: .dev-tools-actions
sparse-checkout: |
.github/actions
- name: Setup PHP and install dependencies
uses: ./.dev-tools-actions/.github/actions/php/setup-composer
with:
php-version: ${{ needs.resolve_php.outputs.php-version }}
root-version: ${{ env.CHANGELOG_ROOT_VERSION }}
install-options: --prefer-dist --no-progress --no-interaction --no-plugins --no-scripts
- name: Resolve release version
id: version
uses: ./.dev-tools-actions/.github/actions/changelog/resolve-version
with:
changelog-file: ${{ env.CHANGELOG_FILE }}
version: ${{ inputs.version || '' }}
- name: Promote changelog release
env:
RELEASE_VERSION: ${{ steps.version.outputs.value }}
run: |
release_date="$(date -u +%F)"
composer dev-tools changelog:promote -- "${RELEASE_VERSION}" --file="${CHANGELOG_FILE}" --date="${release_date}"
- name: Render release notes preview
uses: ./.dev-tools-actions/.github/actions/changelog/render-release-notes
with:
changelog-file: ${{ env.CHANGELOG_FILE }}
version: ${{ steps.version.outputs.value }}
- name: Create release preparation pull request
id: create_pr
uses: peter-evans/create-pull-request@v8
with:
token: ${{ github.token }}
branch: ${{ env.RELEASE_BRANCH_PREFIX }}${{ steps.version.outputs.value }}
delete-branch: false
base: ${{ github.event.repository.default_branch }}
add-paths: |
${{ env.CHANGELOG_FILE }}
commit-message: Prepare release v${{ steps.version.outputs.value }}
title: Prepare release v${{ steps.version.outputs.value }}
body: |
## Summary
- promote `Unreleased` into `${{ steps.version.outputs.value }}`
- prepare the GitHub release body from `${{ env.CHANGELOG_FILE }}`
## Version Resolution
- source: `${{ steps.version.outputs.source }}`
- uses: actions/checkout@v6
- name: Checkout dev-tools workflow action source
uses: actions/checkout@v6
with:
repository: php-fast-forward/dev-tools
ref: ${{ github.repository == 'php-fast-forward/dev-tools' && (github.event_name == 'pull_request_target' && github.event.pull_request.base.sha || github.sha) || 'main' }}
path: .dev-tools-actions
sparse-checkout: |
.github/actions
- uses: ./.dev-tools-actions/.github/actions/project-board/transition-status
with:
project: ${{ inputs.project || vars.PROJECT || '' }}
from-status: Merged
to-status: Release Prepared
- uses: ./.dev-tools-actions/.github/actions/summary/write
with:
markdown: |
## Release Preparation Summary
- Changelog file: `${{ env.CHANGELOG_FILE }}`
- Release version: `${{ steps.version.outputs.value }}`
- Version source: `${{ steps.version.outputs.source }}`
- Pull request operation: `${{ steps.create_pr.outputs.pull-request-operation || 'none' }}`
- Pull request URL: ${{ steps.create_pr.outputs.pull-request-url || 'not created' }}
publish_merged_release:
name: Publish Merged Release
needs: resolve_php
if: ${{ github.event.pull_request.merged == true && github.event.pull_request.base.ref == github.event.repository.default_branch && github.event.pull_request.head.repo.full_name == github.repository && startsWith(github.event.pull_request.head.ref, inputs.release-branch-prefix || 'release/v') }}
runs-on: ubuntu-latest
env:
CHANGELOG_FILE: ${{ inputs.changelog-file || 'CHANGELOG.md' }}
RELEASE_BRANCH_PREFIX: ${{ inputs.release-branch-prefix || 'release/v' }}
CHANGELOG_ROOT_VERSION: ${{ format('dev-{0}', github.event.repository.default_branch) }}
steps:
- uses: actions/checkout@v6
with:
token: ${{ github.token }}
ref: ${{ github.event.pull_request.base.ref }}
fetch-depth: 0
- name: Checkout dev-tools workflow action source
uses: actions/checkout@v6
with:
repository: php-fast-forward/dev-tools
ref: ${{ github.repository == 'php-fast-forward/dev-tools' && (github.event_name == 'pull_request_target' && github.event.pull_request.base.sha || github.sha) || 'main' }}
path: .dev-tools-actions
sparse-checkout: |
.github/actions
- name: Setup PHP and install dependencies
uses: ./.dev-tools-actions/.github/actions/php/setup-composer
with:
php-version: ${{ needs.resolve_php.outputs.php-version }}
root-version: ${{ env.CHANGELOG_ROOT_VERSION }}
install-options: --prefer-dist --no-progress --no-interaction --no-plugins --no-scripts
- name: Resolve merged release version
id: version
uses: ./.dev-tools-actions/.github/actions/changelog/resolve-merged-version
with:
head-ref: ${{ github.event.pull_request.head.ref }}
release-branch-prefix: ${{ env.RELEASE_BRANCH_PREFIX }}
- name: Render release notes
uses: ./.dev-tools-actions/.github/actions/changelog/render-release-notes
with:
changelog-file: ${{ env.CHANGELOG_FILE }}
version: ${{ steps.version.outputs.value }}
- name: Publish GitHub release
id: publish_release
uses: ./.dev-tools-actions/.github/actions/changelog/publish-release
with:
version: ${{ steps.version.outputs.value }}
target: ${{ github.event.pull_request.merge_commit_sha || github.sha }}
- uses: actions/checkout@v6
- name: Checkout dev-tools workflow action source
uses: actions/checkout@v6
with:
repository: php-fast-forward/dev-tools
ref: ${{ github.repository == 'php-fast-forward/dev-tools' && (github.event_name == 'pull_request_target' && github.event.pull_request.base.sha || github.sha) || 'main' }}
path: .dev-tools-actions
sparse-checkout: |
.github/actions
- uses: ./.dev-tools-actions/.github/actions/project-board/transition-status
with:
project: ${{ inputs.project || vars.PROJECT || '' }}
from-status: Release Prepared
to-status: Released
include-current-pull-request: 'true'
- uses: ./.dev-tools-actions/.github/actions/summary/write
with:
markdown: |
## Release Publication Summary
- Changelog file: `${{ env.CHANGELOG_FILE }}`
- Published tag: `v${{ steps.version.outputs.value }}`
- Release operation: `${{ steps.publish_release.outputs.operation }}`
- Release URL: ${{ steps.publish_release.outputs.url }}