|
| 1 | +# This action requires that any PR targeting the main branch should add a |
| 2 | +# changelog fragment file in a .changelog/ directory under the affected |
| 3 | +# package. If a changelog entry is not required, add the "Skip Changelog" |
| 4 | +# label to disable this action. |
| 5 | + |
| 6 | +name: changelog |
| 7 | + |
| 8 | +on: |
| 9 | + pull_request: |
| 10 | + types: [opened, synchronize, reopened, labeled, unlabeled] |
| 11 | + branches: |
| 12 | + - main |
| 13 | + |
| 14 | +permissions: |
| 15 | + contents: read |
| 16 | + |
| 17 | +jobs: |
| 18 | + changelog: |
| 19 | + runs-on: ubuntu-latest |
| 20 | + if: ${{ !contains(github.event.pull_request.labels.*.name, 'Skip Changelog') }} |
| 21 | + |
| 22 | + steps: |
| 23 | + - uses: actions/checkout@v4 |
| 24 | + with: |
| 25 | + fetch-depth: 0 |
| 26 | + |
| 27 | + - name: Fetch base branch |
| 28 | + run: git fetch origin ${{ github.base_ref }} --depth=1 |
| 29 | + |
| 30 | + - name: Ensure no direct changes to CHANGELOG.md |
| 31 | + run: | |
| 32 | + if [[ $(git diff --name-only FETCH_HEAD -- '**/CHANGELOG.md') ]] |
| 33 | + then |
| 34 | + echo "CHANGELOG.md files should not be directly modified." |
| 35 | + echo "Please add a changelog fragment file to the affected package's .changelog/ directory instead." |
| 36 | + echo "See CONTRIBUTING.md for details." |
| 37 | + echo "" |
| 38 | + echo "Or add the \"Skip Changelog\" label if this job should be skipped." |
| 39 | + false |
| 40 | + fi |
| 41 | +
|
| 42 | + - name: Check for changelog fragment |
| 43 | + env: |
| 44 | + PR_NUMBER: ${{ github.event.pull_request.number }} |
| 45 | + run: | |
| 46 | + fragments=$(git diff --diff-filter=A --name-only FETCH_HEAD -- '**/.changelog/*' | grep -v '/\.gitignore$' || true) |
| 47 | + if [[ -z "$fragments" ]]; then |
| 48 | + echo "No changelog fragment found for this PR." |
| 49 | + echo "" |
| 50 | + echo "Add a file named <package>/.changelog/${PR_NUMBER}.<type>" |
| 51 | + echo "where <type> is one of: added, changed, deprecated, removed, fixed" |
| 52 | + echo "" |
| 53 | + echo "See CONTRIBUTING.md for details." |
| 54 | + echo "" |
| 55 | + echo "Or add the \"Skip Changelog\" label if this job should be skipped." |
| 56 | + exit 1 |
| 57 | + fi |
| 58 | + invalid=() |
| 59 | + while IFS= read -r f; do |
| 60 | + base=$(basename "$f") |
| 61 | + if [[ ! "$base" =~ ^([0-9]+)\.(added|changed|deprecated|removed|fixed)$ ]]; then |
| 62 | + invalid+=("$f (expected <PR_NUMBER>.<type>; type one of added, changed, deprecated, removed, fixed)") |
| 63 | + continue |
| 64 | + fi |
| 65 | + if [[ "${BASH_REMATCH[1]}" != "${PR_NUMBER}" ]]; then |
| 66 | + invalid+=("$f (PR number ${BASH_REMATCH[1]} does not match this PR's number ${PR_NUMBER})") |
| 67 | + fi |
| 68 | + done <<< "$fragments" |
| 69 | + if (( ${#invalid[@]} > 0 )); then |
| 70 | + echo "Invalid changelog fragment(s):" |
| 71 | + for msg in "${invalid[@]}"; do |
| 72 | + echo " $msg" |
| 73 | + done |
| 74 | + exit 1 |
| 75 | + fi |
| 76 | + echo "Found changelog fragment(s):" |
| 77 | + echo "$fragments" |
| 78 | +
|
| 79 | + - name: Set up Python |
| 80 | + uses: actions/setup-python@v5 |
| 81 | + with: |
| 82 | + python-version: "3.14" |
| 83 | + |
| 84 | + - name: Install towncrier |
| 85 | + run: pip install towncrier==25.8.0 |
| 86 | + |
| 87 | + - name: Preview changelogs |
| 88 | + run: | |
| 89 | + set -eu |
| 90 | + for pkg in instrumentation/* util/opentelemetry-util-genai; do |
| 91 | + [ -f "$pkg/pyproject.toml" ] || continue |
| 92 | + grep -q "tool.towncrier" "$pkg/pyproject.toml" || continue |
| 93 | + echo "=== $pkg ===" |
| 94 | + (cd "$pkg" && towncrier build --draft --version Unreleased) |
| 95 | + done |
0 commit comments