From 2f4e62c0f06ffb71e7a980955a06cca544efefb9 Mon Sep 17 00:00:00 2001 From: Harshit Kushwaha Date: Fri, 15 May 2026 03:15:28 -0400 Subject: [PATCH 1/4] [chore] Implement chloggen fragment automation for releases (#2787) --- .chloggen/TEMPLATE.yaml | 12 ++ .chloggen/config.yaml | 12 ++ .github/workflows/changelog-fragment.yml | 199 ++++++++++++++++++ .github/workflows/draft-release-changelog.yml | 46 ++++ 4 files changed, 269 insertions(+) create mode 100644 .chloggen/TEMPLATE.yaml create mode 100644 .chloggen/config.yaml create mode 100644 .github/workflows/changelog-fragment.yml create mode 100644 .github/workflows/draft-release-changelog.yml diff --git a/.chloggen/TEMPLATE.yaml b/.chloggen/TEMPLATE.yaml new file mode 100644 index 000000000..b3236af1a --- /dev/null +++ b/.chloggen/TEMPLATE.yaml @@ -0,0 +1,12 @@ +# Valid change types: +# - breaking +# - deprecation +# - new_component +# - enhancement +# - bug_fix +change_type: +component: jmx-metrics +note: +issues: [] +subtext: +change_logs: [user] \ No newline at end of file diff --git a/.chloggen/config.yaml b/.chloggen/config.yaml new file mode 100644 index 000000000..064417223 --- /dev/null +++ b/.chloggen/config.yaml @@ -0,0 +1,12 @@ +change_types: + - breaking + - deprecation + - new_component + - enhancement + - bug_fix +entries_dir: .chloggen +changelog_md: CHANGELOG.md +template_yaml: .chloggen/TEMPLATE.yaml +change_logs: + user: CHANGELOG.md +default_change_logs: [user] \ No newline at end of file diff --git a/.github/workflows/changelog-fragment.yml b/.github/workflows/changelog-fragment.yml new file mode 100644 index 000000000..48a6b34a1 --- /dev/null +++ b/.github/workflows/changelog-fragment.yml @@ -0,0 +1,199 @@ +name: Changelog Fragments + +on: + pull_request: + types: + - opened + - synchronize + - reopened + - labeled + - unlabeled + +permissions: + contents: write + issues: write + pull-requests: write + models: read + +jobs: + generate-fragment: + if: ${{ github.actor != 'dependabot[bot]' && github.actor != 'renovate[bot]' }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + repository: ${{ github.event.pull_request.head.repo.full_name }} + ref: ${{ github.head_ref }} + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 + + - name: Check skip conditions + id: skip + env: + PR_TITLE: ${{ github.event.pull_request.title }} + PR_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }} + run: | + skip=false + + if [[ $PR_TITLE == \[chore\]* ]]; then + skip=true + fi + + if jq -e 'index("Skip Changelog")' <<<"$PR_LABELS" >/dev/null; then + skip=true + fi + + echo "skip=$skip" >> "$GITHUB_OUTPUT" + + - name: Check existing fragment + id: fragment + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + fragment=".chloggen/pr-${PR_NUMBER}.yaml" + + if [[ -f "$fragment" ]]; then + echo "exists=true" >> "$GITHUB_OUTPUT" + else + echo "exists=false" >> "$GITHUB_OUTPUT" + fi + + - name: Install yq + if: ${{ steps.skip.outputs.skip != 'true' && steps.fragment.outputs.exists != 'true' && github.event.pull_request.head.repo.full_name == github.repository }} + run: | + go install github.com/mikefarah/yq/v4@latest + echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" + + - name: Fetch base branch + if: ${{ steps.skip.outputs.skip != 'true' && steps.fragment.outputs.exists != 'true' && github.event.pull_request.head.repo.full_name == github.repository }} + run: | + git fetch origin "${{ github.event.pull_request.base.ref }}:refs/remotes/origin/${{ github.event.pull_request.base.ref }}" --depth=1 + + - name: Generate changelog fragment from GitHub Models + if: ${{ steps.skip.outputs.skip != 'true' && steps.fragment.outputs.exists != 'true' && github.event.pull_request.head.repo.full_name == github.repository }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_NUMBER: ${{ github.event.pull_request.number }} + PR_TITLE: ${{ github.event.pull_request.title }} + PR_BODY: ${{ github.event.pull_request.body }} + BASE_REF: ${{ github.event.pull_request.base.ref }} + run: | + changed_files="$(git diff --name-only "origin/${BASE_REF}"...HEAD)" + + request_payload="$(jq -n \ + --arg title "$PR_TITLE" \ + --arg body "$PR_BODY" \ + --arg changed_files "$changed_files" \ + '{ + model: "gpt-4o-mini", + response_format: {type: "json_object"}, + messages: [ + { + role: "system", + content: "Generate a single JSON object for a changelog fragment. Return only valid JSON with these keys: change_type, component, note, issues, subtext, change_logs. change_type must be one of breaking, deprecation, new_component, enhancement, bug_fix. component must be a concise repository component or area such as jmx-metrics. note must be a brief end-user facing summary. issues must be an array of issue numbers without #. subtext is optional and may be null or omitted. change_logs must be [\"user\"]. Do not add markdown or extra keys." + }, + { + role: "user", + content: "PR title: \($title)\n\nPR body:\n\($body)\n\nChanged files:\n\($changed_files)" + } + ] + }')" + + response="$(curl --fail-with-body --silent --show-error https://models.inference.ai.azure.com/chat/completions \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${GITHUB_TOKEN}" \ + -d "$request_payload")" + + jq -r '.choices[0].message.content | fromjson' <<<"$response" | yq -P - > ".chloggen/pr-${PR_NUMBER}.yaml" + + - name: Commit changelog fragment + if: ${{ steps.skip.outputs.skip != 'true' && steps.fragment.outputs.exists != 'true' && github.event.pull_request.head.repo.full_name == github.repository }} + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + PR_BRANCH: ${{ github.head_ref }} + run: | + git config user.name opentelemetrybot + git config user.email 107717825+opentelemetrybot@users.noreply.github.com + git add ".chloggen/pr-${PR_NUMBER}.yaml" + git commit -m "Add changelog fragment for PR #${PR_NUMBER}" + git push origin HEAD:"${PR_BRANCH}" + + - name: Ask fork contributors to add a fragment manually + if: ${{ steps.skip.outputs.skip != 'true' && steps.fragment.outputs.exists != 'true' && github.event.pull_request.head.repo.full_name != github.repository }} + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + { + echo "I could not generate a changelog fragment automatically because this pull request comes from a fork." + echo + echo "Please add the following file manually at .chloggen/pr-${PR_NUMBER}.yaml:" + echo + echo '```yaml' + printf '%s\n' \ + '# Valid change types:' \ + '# - breaking' \ + '# - deprecation' \ + '# - new_component' \ + '# - enhancement' \ + '# - bug_fix' \ + 'change_type:' \ + 'component: jmx-metrics' \ + 'note:' \ + 'issues: []' \ + 'subtext:' \ + 'change_logs: [user]' + echo '```' + } > /tmp/changelog-comment.md + + gh pr comment "${PR_NUMBER}" --body-file /tmp/changelog-comment.md + + validate-fragment: + needs: generate-fragment + if: always() + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + repository: ${{ github.event.pull_request.head.repo.full_name }} + ref: ${{ github.head_ref }} + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 + + - name: Check skip conditions + id: skip + env: + PR_TITLE: ${{ github.event.pull_request.title }} + PR_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }} + run: | + skip=false + + if [[ $PR_TITLE == \[chore\]* ]]; then + skip=true + fi + + if jq -e 'index("Skip Changelog")' <<<"$PR_LABELS" >/dev/null; then + skip=true + fi + + echo "skip=$skip" >> "$GITHUB_OUTPUT" + + - name: Install chloggen + if: ${{ steps.skip.outputs.skip != 'true' }} + run: | + go install go.opentelemetry.io/build-tools/chloggen@latest + echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" + + - name: Verify changelog fragment + if: ${{ steps.skip.outputs.skip != 'true' }} + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + fragment=".chloggen/pr-${PR_NUMBER}.yaml" + + if [[ ! -f "$fragment" ]]; then + echo "missing changelog fragment: $fragment" + exit 1 + fi + + chloggen validate --config .chloggen/config.yaml diff --git a/.github/workflows/draft-release-changelog.yml b/.github/workflows/draft-release-changelog.yml new file mode 100644 index 000000000..805c387f1 --- /dev/null +++ b/.github/workflows/draft-release-changelog.yml @@ -0,0 +1,46 @@ +name: Draft Release Changelog + +on: + workflow_dispatch: + inputs: + version: + description: Version to compile into the changelog + required: true + type: string + +permissions: + contents: write + pull-requests: write + +jobs: + compile-changelog: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install chloggen + run: | + go install go.opentelemetry.io/build-tools/chloggen@latest + echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" + + - name: Preview changelog update + run: | + chloggen update --config .chloggen/config.yaml --dry + + - name: Compile changelog fragments + run: | + chloggen update --config .chloggen/config.yaml --version "${{ inputs.version }}" + + - uses: peter-evans/create-pull-request@v6 + with: + token: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + branch: chore/changelog-${{ inputs.version }} + commit-message: "Update changelog for ${{ inputs.version }}" + title: "chore: update changelog for ${{ inputs.version }}" + body: | + Compile changelog fragments for version ${{ inputs.version }}. + author: opentelemetrybot <107717825+opentelemetrybot@users.noreply.github.com> + committer: opentelemetrybot <107717825+opentelemetrybot@users.noreply.github.com> + delete-branch: true \ No newline at end of file From 3b1a7223441b93de4f0666fa9a0b7f944e096a30 Mon Sep 17 00:00:00 2001 From: Harshit Kushwaha Date: Fri, 15 May 2026 04:00:00 -0400 Subject: [PATCH 2/4] [chore] Address review feedback for changelog automation --- .chloggen/TEMPLATE.yaml | 2 +- .github/workflows/changelog-fragment.yml | 68 +++++++++++++------ .github/workflows/draft-release-changelog.yml | 9 ++- 3 files changed, 55 insertions(+), 24 deletions(-) diff --git a/.chloggen/TEMPLATE.yaml b/.chloggen/TEMPLATE.yaml index b3236af1a..b08d98783 100644 --- a/.chloggen/TEMPLATE.yaml +++ b/.chloggen/TEMPLATE.yaml @@ -5,7 +5,7 @@ # - enhancement # - bug_fix change_type: -component: jmx-metrics +component: note: issues: [] subtext: diff --git a/.github/workflows/changelog-fragment.yml b/.github/workflows/changelog-fragment.yml index 48a6b34a1..469946e1a 100644 --- a/.github/workflows/changelog-fragment.yml +++ b/.github/workflows/changelog-fragment.yml @@ -17,7 +17,6 @@ permissions: jobs: generate-fragment: - if: ${{ github.actor != 'dependabot[bot]' && github.actor != 'renovate[bot]' }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -27,15 +26,25 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} fetch-depth: 0 + - name: Install yq + run: | + go install github.com/mikefarah/yq/v4@v4.44.3 + echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" + - name: Check skip conditions id: skip env: PR_TITLE: ${{ github.event.pull_request.title }} PR_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }} + PR_ACTOR: ${{ github.actor }} run: | skip=false - if [[ $PR_TITLE == \[chore\]* ]]; then + if [[ "$PR_ACTOR" == "dependabot[bot]" || "$PR_ACTOR" == "renovate[bot]" ]]; then + skip=true + fi + + if [[ "$PR_TITLE" == \[chore\]* ]]; then skip=true fi @@ -58,18 +67,12 @@ jobs: echo "exists=false" >> "$GITHUB_OUTPUT" fi - - name: Install yq - if: ${{ steps.skip.outputs.skip != 'true' && steps.fragment.outputs.exists != 'true' && github.event.pull_request.head.repo.full_name == github.repository }} - run: | - go install github.com/mikefarah/yq/v4@latest - echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" - - name: Fetch base branch if: ${{ steps.skip.outputs.skip != 'true' && steps.fragment.outputs.exists != 'true' && github.event.pull_request.head.repo.full_name == github.repository }} run: | git fetch origin "${{ github.event.pull_request.base.ref }}:refs/remotes/origin/${{ github.event.pull_request.base.ref }}" --depth=1 - - name: Generate changelog fragment from GitHub Models + - name: Generate fragment if: ${{ steps.skip.outputs.skip != 'true' && steps.fragment.outputs.exists != 'true' && github.event.pull_request.head.repo.full_name == github.repository }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -90,7 +93,7 @@ jobs: messages: [ { role: "system", - content: "Generate a single JSON object for a changelog fragment. Return only valid JSON with these keys: change_type, component, note, issues, subtext, change_logs. change_type must be one of breaking, deprecation, new_component, enhancement, bug_fix. component must be a concise repository component or area such as jmx-metrics. note must be a brief end-user facing summary. issues must be an array of issue numbers without #. subtext is optional and may be null or omitted. change_logs must be [\"user\"]. Do not add markdown or extra keys." + content: "Generate a single JSON object for a changelog fragment. Return only valid JSON with these keys: change_type, component, note, issues, subtext, change_logs. change_type must be one of breaking, deprecation, new_component, enhancement, bug_fix. component must be blank if the PR does not clearly map to one component. note must be a brief end-user facing summary. issues must be an array of issue numbers without #. subtext is optional and may be null or omitted. change_logs must be [\"user\"]. Do not add markdown or extra keys." }, { role: "user", @@ -99,14 +102,30 @@ jobs: ] }')" - response="$(curl --fail-with-body --silent --show-error https://models.inference.ai.azure.com/chat/completions \ + response="$(curl --fail-with-body --silent --show-error https://models.github.ai/inference/chat/completions \ + -H "Accept: application/vnd.github+json" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${GITHUB_TOKEN}" \ -d "$request_payload")" jq -r '.choices[0].message.content | fromjson' <<<"$response" | yq -P - > ".chloggen/pr-${PR_NUMBER}.yaml" - - name: Commit changelog fragment + - name: Validate AI Output + if: ${{ steps.skip.outputs.skip != 'true' && steps.fragment.outputs.exists != 'true' && github.event.pull_request.head.repo.full_name == github.repository }} + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + fragment=".chloggen/pr-${PR_NUMBER}.yaml" + + go install go.opentelemetry.io/build-tools/chloggen@v0.15.0 + echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" + + if ! chloggen validate --config .chloggen/config.yaml; then + rm -f "$fragment" + exit 1 + fi + + - name: Commit if: ${{ steps.skip.outputs.skip != 'true' && steps.fragment.outputs.exists != 'true' && github.event.pull_request.head.repo.full_name == github.repository }} env: PR_NUMBER: ${{ github.event.pull_request.number }} @@ -118,7 +137,7 @@ jobs: git commit -m "Add changelog fragment for PR #${PR_NUMBER}" git push origin HEAD:"${PR_BRANCH}" - - name: Ask fork contributors to add a fragment manually + - name: Fork comment fallback if: ${{ steps.skip.outputs.skip != 'true' && steps.fragment.outputs.exists != 'true' && github.event.pull_request.head.repo.full_name != github.repository }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -138,7 +157,7 @@ jobs: '# - enhancement' \ '# - bug_fix' \ 'change_type:' \ - 'component: jmx-metrics' \ + 'component:' \ 'note:' \ 'issues: []' \ 'subtext:' \ @@ -146,7 +165,7 @@ jobs: echo '```' } > /tmp/changelog-comment.md - gh pr comment "${PR_NUMBER}" --body-file /tmp/changelog-comment.md + gh pr comment --repo "${{ github.repository }}" "${PR_NUMBER}" --body-file /tmp/changelog-comment.md validate-fragment: needs: generate-fragment @@ -165,10 +184,15 @@ jobs: env: PR_TITLE: ${{ github.event.pull_request.title }} PR_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }} + PR_ACTOR: ${{ github.actor }} run: | skip=false - if [[ $PR_TITLE == \[chore\]* ]]; then + if [[ "$PR_ACTOR" == "dependabot[bot]" || "$PR_ACTOR" == "renovate[bot]" ]]; then + skip=true + fi + + if [[ "$PR_TITLE" == \[chore\]* ]]; then skip=true fi @@ -178,13 +202,11 @@ jobs: echo "skip=$skip" >> "$GITHUB_OUTPUT" - - name: Install chloggen - if: ${{ steps.skip.outputs.skip != 'true' }} - run: | - go install go.opentelemetry.io/build-tools/chloggen@latest - echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" + - name: Exit if skipped + if: ${{ steps.skip.outputs.skip == 'true' }} + run: exit 0 - - name: Verify changelog fragment + - name: Validate fragment if: ${{ steps.skip.outputs.skip != 'true' }} env: PR_NUMBER: ${{ github.event.pull_request.number }} @@ -196,4 +218,6 @@ jobs: exit 1 fi + go install go.opentelemetry.io/build-tools/chloggen@v0.15.0 + echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" chloggen validate --config .chloggen/config.yaml diff --git a/.github/workflows/draft-release-changelog.yml b/.github/workflows/draft-release-changelog.yml index 805c387f1..c99d989d6 100644 --- a/.github/workflows/draft-release-changelog.yml +++ b/.github/workflows/draft-release-changelog.yml @@ -20,9 +20,16 @@ jobs: with: fetch-depth: 0 + - name: Validate version input + run: | + if [[ ! "${{ inputs.version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "❌ Invalid version format: ${{ inputs.version }}. Must be X.Y.Z" + exit 1 + fi + - name: Install chloggen run: | - go install go.opentelemetry.io/build-tools/chloggen@latest + go install go.opentelemetry.io/build-tools/chloggen@v0.15.0 echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" - name: Preview changelog update From ee3c826f7173815aa212c122a49c1bcaff72e46f Mon Sep 17 00:00:00 2001 From: Harshit Kushwaha Date: Fri, 15 May 2026 04:50:20 -0400 Subject: [PATCH 3/4] [chore] Harden changelog automation against CI edge cases Signed-off-by: Harshit Kushwaha --- .chloggen/TEMPLATE.yaml | 14 ++--- .github/workflows/changelog-fragment.yml | 55 ++++--------------- .github/workflows/draft-release-changelog.yml | 50 ++++++++--------- 3 files changed, 42 insertions(+), 77 deletions(-) diff --git a/.chloggen/TEMPLATE.yaml b/.chloggen/TEMPLATE.yaml index b08d98783..4487b5f6d 100644 --- a/.chloggen/TEMPLATE.yaml +++ b/.chloggen/TEMPLATE.yaml @@ -1,12 +1,12 @@ -# Valid change types: -# - breaking -# - deprecation -# - new_component -# - enhancement -# - bug_fix +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' change_type: -component: +# The name of the component (e.g. jmx-metrics, resource-providers, aws-xray) +component: +# A brief description of the change. note: +# One or more tracking issues related to the change. Use the PR number if no issue exists. issues: [] +# Optional additional context. subtext: +# 'user' if relevant to end users, 'api' if there is a library API change. change_logs: [user] \ No newline at end of file diff --git a/.github/workflows/changelog-fragment.yml b/.github/workflows/changelog-fragment.yml index 469946e1a..555f0add3 100644 --- a/.github/workflows/changelog-fragment.yml +++ b/.github/workflows/changelog-fragment.yml @@ -23,24 +23,23 @@ jobs: with: repository: ${{ github.event.pull_request.head.repo.full_name }} ref: ${{ github.head_ref }} - token: ${{ secrets.GITHUB_TOKEN }} + token: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} fetch-depth: 0 - name: Install yq run: | go install github.com/mikefarah/yq/v4@v4.44.3 - echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" - name: Check skip conditions id: skip env: PR_TITLE: ${{ github.event.pull_request.title }} PR_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }} - PR_ACTOR: ${{ github.actor }} + PR_USER_LOGIN: ${{ github.event.pull_request.user.login }} run: | skip=false - if [[ "$PR_ACTOR" == "dependabot[bot]" || "$PR_ACTOR" == "renovate[bot]" ]]; then + if [[ "$PR_USER_LOGIN" == "dependabot[bot]" || "$PR_USER_LOGIN" == "renovate[bot]" ]]; then skip=true fi @@ -108,7 +107,7 @@ jobs: -H "Authorization: Bearer ${GITHUB_TOKEN}" \ -d "$request_payload")" - jq -r '.choices[0].message.content | fromjson' <<<"$response" | yq -P - > ".chloggen/pr-${PR_NUMBER}.yaml" + jq -r '.choices[0].message.content | fromjson' <<<"$response" | "$(go env GOPATH)/bin/yq" -P - > ".chloggen/pr-${PR_NUMBER}.yaml" - name: Validate AI Output if: ${{ steps.skip.outputs.skip != 'true' && steps.fragment.outputs.exists != 'true' && github.event.pull_request.head.repo.full_name == github.repository }} @@ -117,10 +116,8 @@ jobs: run: | fragment=".chloggen/pr-${PR_NUMBER}.yaml" - go install go.opentelemetry.io/build-tools/chloggen@v0.15.0 - echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" - - if ! chloggen validate --config .chloggen/config.yaml; then + if ! "$(go env GOPATH)/bin/yq" -e 'has("change_type") and has("component") and has("note")' "$fragment" >/dev/null; then + echo "missing required keys: change_type, component, note" rm -f "$fragment" exit 1 fi @@ -137,36 +134,6 @@ jobs: git commit -m "Add changelog fragment for PR #${PR_NUMBER}" git push origin HEAD:"${PR_BRANCH}" - - name: Fork comment fallback - if: ${{ steps.skip.outputs.skip != 'true' && steps.fragment.outputs.exists != 'true' && github.event.pull_request.head.repo.full_name != github.repository }} - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PR_NUMBER: ${{ github.event.pull_request.number }} - run: | - { - echo "I could not generate a changelog fragment automatically because this pull request comes from a fork." - echo - echo "Please add the following file manually at .chloggen/pr-${PR_NUMBER}.yaml:" - echo - echo '```yaml' - printf '%s\n' \ - '# Valid change types:' \ - '# - breaking' \ - '# - deprecation' \ - '# - new_component' \ - '# - enhancement' \ - '# - bug_fix' \ - 'change_type:' \ - 'component:' \ - 'note:' \ - 'issues: []' \ - 'subtext:' \ - 'change_logs: [user]' - echo '```' - } > /tmp/changelog-comment.md - - gh pr comment --repo "${{ github.repository }}" "${PR_NUMBER}" --body-file /tmp/changelog-comment.md - validate-fragment: needs: generate-fragment if: always() @@ -176,7 +143,7 @@ jobs: with: repository: ${{ github.event.pull_request.head.repo.full_name }} ref: ${{ github.head_ref }} - token: ${{ secrets.GITHUB_TOKEN }} + token: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} fetch-depth: 0 - name: Check skip conditions @@ -184,11 +151,11 @@ jobs: env: PR_TITLE: ${{ github.event.pull_request.title }} PR_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }} - PR_ACTOR: ${{ github.actor }} + PR_USER_LOGIN: ${{ github.event.pull_request.user.login }} run: | skip=false - if [[ "$PR_ACTOR" == "dependabot[bot]" || "$PR_ACTOR" == "renovate[bot]" ]]; then + if [[ "$PR_USER_LOGIN" == "dependabot[bot]" || "$PR_USER_LOGIN" == "renovate[bot]" ]]; then skip=true fi @@ -207,7 +174,6 @@ jobs: run: exit 0 - name: Validate fragment - if: ${{ steps.skip.outputs.skip != 'true' }} env: PR_NUMBER: ${{ github.event.pull_request.number }} run: | @@ -219,5 +185,4 @@ jobs: fi go install go.opentelemetry.io/build-tools/chloggen@v0.15.0 - echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" - chloggen validate --config .chloggen/config.yaml + "$(go env GOPATH)/bin/chloggen" validate --config .chloggen/config.yaml diff --git a/.github/workflows/draft-release-changelog.yml b/.github/workflows/draft-release-changelog.yml index c99d989d6..b92557c41 100644 --- a/.github/workflows/draft-release-changelog.yml +++ b/.github/workflows/draft-release-changelog.yml @@ -4,22 +4,22 @@ on: workflow_dispatch: inputs: version: - description: Version to compile into the changelog + description: 'Release version (e.g. 1.57.0)' required: true type: string -permissions: - contents: write - pull-requests: write - jobs: - compile-changelog: + draft-changelog: runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - + - name: Validate version input run: | if [[ ! "${{ inputs.version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then @@ -28,26 +28,26 @@ jobs: fi - name: Install chloggen - run: | - go install go.opentelemetry.io/build-tools/chloggen@v0.15.0 - echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" + run: go install go.opentelemetry.io/build-tools/chloggen@v0.15.0 - - name: Preview changelog update - run: | - chloggen update --config .chloggen/config.yaml --dry + - name: Dry run (preview) + run: $(go env GOPATH)/bin/chloggen update --dry - - name: Compile changelog fragments - run: | - chloggen update --config .chloggen/config.yaml --version "${{ inputs.version }}" + - name: Compile changelog + run: $(go env GOPATH)/bin/chloggen update --version ${{ inputs.version }} - - uses: peter-evans/create-pull-request@v6 + - name: Create PR for Release Captain review + uses: peter-evans/create-pull-request@v6 with: - token: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - branch: chore/changelog-${{ inputs.version }} - commit-message: "Update changelog for ${{ inputs.version }}" - title: "chore: update changelog for ${{ inputs.version }}" + # Strictly require the bot token for EasyCLA compliance + token: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }} + commit-message: "[chore] update changelog for release ${{ inputs.version }}" + committer: "opentelemetrybot <107717825+opentelemetrybot@users.noreply.github.com>" + author: "opentelemetrybot <107717825+opentelemetrybot@users.noreply.github.com>" + title: "[chore] update changelog for release ${{ inputs.version }}" body: | - Compile changelog fragments for version ${{ inputs.version }}. - author: opentelemetrybot <107717825+opentelemetrybot@users.noreply.github.com> - committer: opentelemetrybot <107717825+opentelemetrybot@users.noreply.github.com> - delete-branch: true \ No newline at end of file + Automated changelog compilation for release `${{ inputs.version }}`. + + **Release Captain:** Review the entries below, make any manual corrections, then merge. + branch: "chore/changelog-${{ inputs.version }}" + base: main \ No newline at end of file From 77983cd845b87a9057a9e9e5f54d814352fab2d2 Mon Sep 17 00:00:00 2001 From: Harshit Kushwaha Date: Fri, 15 May 2026 05:05:59 -0400 Subject: [PATCH 4/4] chore: Update changelog automation to use GitHub token and enhance error messaging Signed-off-by: Harshit Kushwaha --- .chloggen/pr-2837.yaml | 6 ++++++ .github/workflows/changelog-fragment.yml | 8 +++++--- .github/workflows/draft-release-changelog.yml | 4 +++- 3 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 .chloggen/pr-2837.yaml diff --git a/.chloggen/pr-2837.yaml b/.chloggen/pr-2837.yaml new file mode 100644 index 000000000..ced5eabcd --- /dev/null +++ b/.chloggen/pr-2837.yaml @@ -0,0 +1,6 @@ +change_type: enhancement +component: +note: Automate changelog generation using fragment pattern +issues: [2787] +subtext: +change_logs: [user] diff --git a/.github/workflows/changelog-fragment.yml b/.github/workflows/changelog-fragment.yml index 555f0add3..5f6e02de4 100644 --- a/.github/workflows/changelog-fragment.yml +++ b/.github/workflows/changelog-fragment.yml @@ -23,7 +23,7 @@ jobs: with: repository: ${{ github.event.pull_request.head.repo.full_name }} ref: ${{ github.head_ref }} - token: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + token: ${{ github.token }} fetch-depth: 0 - name: Install yq @@ -143,7 +143,7 @@ jobs: with: repository: ${{ github.event.pull_request.head.repo.full_name }} ref: ${{ github.head_ref }} - token: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + token: ${{ github.token }} fetch-depth: 0 - name: Check skip conditions @@ -180,7 +180,9 @@ jobs: fragment=".chloggen/pr-${PR_NUMBER}.yaml" if [[ ! -f "$fragment" ]]; then - echo "missing changelog fragment: $fragment" + echo "❌ Missing changelog fragment: $fragment" + echo "If you are contributing from a fork, you must create this file manually." + echo "Copy the contents of .chloggen/TEMPLATE.yaml into a new file named $fragment, fill it out, and commit it to your branch." exit 1 fi diff --git a/.github/workflows/draft-release-changelog.yml b/.github/workflows/draft-release-changelog.yml index b92557c41..c0fa31c79 100644 --- a/.github/workflows/draft-release-changelog.yml +++ b/.github/workflows/draft-release-changelog.yml @@ -34,7 +34,9 @@ jobs: run: $(go env GOPATH)/bin/chloggen update --dry - name: Compile changelog - run: $(go env GOPATH)/bin/chloggen update --version ${{ inputs.version }} + env: + VERSION: ${{ inputs.version }} + run: $(go env GOPATH)/bin/chloggen update --version "$VERSION" - name: Create PR for Release Captain review uses: peter-evans/create-pull-request@v6