This is an automated email from the ASF dual-hosted git repository. pkarwasz pushed a commit to branch feat/dependabot-add-changelog3 in repository https://gitbox.apache.org/repos/asf/logging-parent.git
commit 27bd89985575ffaccbc20b72158ead5f41a429ed Author: Piotr P. Karwasz <[email protected]> AuthorDate: Tue Jun 24 09:04:51 2025 +0200 feat: Split Dependabot workflow into privileged and unprivileged parts This change splits the Dependabot automation into two reusable workflows: * **Unprivileged workflow** (`analyze-dependabot-reusable`): Runs on `pull_request` with no permissions. It analyzes Dependabot PRs and generates metadata safely. * **Privileged workflow** (`process-dependabot-reusable`): Uses the metadata from the unprivileged step to generate changelog files and enable the "auto-merge" option. Requires access to our GPG key and Personal Access Token. --- .github/workflows/analyze-dependabot-reusable.yaml | 55 ++++++++++++++++++++ .github/workflows/process-dependabot-reusable.yaml | 60 ++++++++++++++-------- ...ess-dependabot.yaml => analyze-dependabot.yaml} | 27 +++------- .../modules/ROOT/examples/process-dependabot.yaml | 24 ++++++--- src/site/antora/modules/ROOT/pages/workflows.adoc | 41 +++++++++++++++ 5 files changed, 158 insertions(+), 49 deletions(-) diff --git a/.github/workflows/analyze-dependabot-reusable.yaml b/.github/workflows/analyze-dependabot-reusable.yaml new file mode 100644 index 0000000..a23fad5 --- /dev/null +++ b/.github/workflows/analyze-dependabot-reusable.yaml @@ -0,0 +1,55 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +name: Dependabot Analyze PR + +on: + workflow_call: + +jobs: + + analyze-pull-request: + # Skip this workflow on commits not pushed by Dependabot + if: ${{ github.actor == 'dependabot[bot]' }} + runs-on: ubuntu-latest + + steps: + + - name: Fetch Dependabot metadata + id: dependabot + uses: ppkarwasz/fetch-metadata@feat/multi-versions + with: + github-token: ${{ github.token }} + + # + # Stores the data required by the process-dependabot-reusable workflow as JSON files. + # + - name: Create artifacts + shell: bash + env: + PULL_REQUEST: ${{ toJSON(github.event.pull_request) }} + UPDATED_DEPENDENCIES: ${{ steps.dependabot.outputs.updated-dependencies-json }} + run: | + mkdir -p dependabot-metadata + echo "$PULL_REQUEST" > dependabot-metadata/pull_request.json + echo "$UPDATED_DEPENDENCIES" > dependabot-metadata/updated_dependencies.json + + - name: Upload artifacts + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # 4.6.2 + with: + name: dependabot-metadata + path: dependabot-metadata diff --git a/.github/workflows/process-dependabot-reusable.yaml b/.github/workflows/process-dependabot-reusable.yaml index a976cd5..ecb38ea 100644 --- a/.github/workflows/process-dependabot-reusable.yaml +++ b/.github/workflows/process-dependabot-reusable.yaml @@ -20,18 +20,18 @@ name: Dependabot Process PR on: workflow_call: inputs: - user_name: + user-name: description: The name of the user to use for the commit default: 'ASF Logging Services RM' type: string - user_email: + user-email: description: The email of the user to use for the commit default: '[email protected]' type: string - ref: - description: The branch, tag or SHA to checkout - default: ${{ github.ref }} - type: string + analyze-workflow-run-id: + description: The ID of the workflow run that analyzed the PR + required: true + type: number secrets: AUTO_MERGE_TOKEN: description: GitHub token to enable auto-merge on PR @@ -56,15 +56,36 @@ jobs: steps: - name: Fetch Dependabot metadata - id: dependabot - uses: dependabot/fetch-metadata@08eff52bf64351f401fb50d4972fa95b9f2c2d1b # 2.4.0 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # 4.3.0 with: github-token: ${{ github.token }} + name: dependabot-metadata + path: ${{ runner.temp }}/dependabot-metadata + run-id: ${{ inputs.analyze-workflow-run-id }} + + - name: Process Dependabot metadata + shell: bash + run: | + # Extract the pull request metadata from the downloaded artifact + path="$RUNNER_TEMP/dependabot-metadata" + if [[ ! -f "$path/pull_request.json" ]]; then + echo "Pull request metadata not found at $path/pull_request.json" + exit 1 + fi + if [[ ! -f "$path/updated_dependencies.json" ]]; then + echo "Updated dependencies metadata not found at $path/updated_dependencies.json" + exit 1 + fi + # Extract the required metadata and set it as environment variables + pull_request="$path/pull_request.json" + echo "PR_ID=$(jq -r '.number' < "$pull_request")" >> $GITHUB_ENV + echo "PR_URL=$(jq -r '.html_url' < "$pull_request")" >> $GITHUB_ENV + echo "PR_HEAD_REF=$(jq -r '.head.ref' < "$pull_request")" >> $GITHUB_ENV - name: Check out repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2 with: - ref: ${{ inputs.ref }} + ref: ${{ env.PR_HEAD_REF }} token: ${{ secrets.CONTENT_WRITE_TOKEN }} - name: Install `xmlstarlet` @@ -89,18 +110,16 @@ jobs: - name: Create changelog entries shell: bash - env: - PR_ID: ${{ github.event.pull_request.number }} - PR_URL: ${{ github.event.pull_request.html_url }} - RELEASE_VERSION_MAJOR: ${{ env.RELEASE_VERSION_MAJOR }} - UPDATED_DEPENDENCIES: ${{ steps.dependabot.outputs.updated-dependencies-json }} run: | + PULL_REQUEST="$RUNNER_TEMP/dependabot-metadata/pull_request.json" + UPDATED_DEPENDENCIES="$RUNNER_TEMP/dependabot-metadata/updated_dependencies.json" + # Generates the content of a changelog entry function generate_changelog_entry() { local dependency="$1" - local dependency_name=$(echo "$dependency" | jq -r '.dependencyName' | xmlstarlet esc) - local new_version=$(echo "$dependency" | jq -r '.newVersion' | xmlstarlet esc) local issue_id=$(xmlstarlet esc "$PR_ID") local issue_link=$(xmlstarlet esc "$PR_URL") + local dependency_name=$(echo "$dependency" | jq -r '.dependencyName' | xmlstarlet esc) + local new_version=$(echo "$dependency" | jq -r '.newVersion' | xmlstarlet esc) cat << CHANGELOG_ENTRY <?xml version="1.0" encoding="UTF-8"?> <!-- SPDX-License-Identifier: Apache-2.0 --> @@ -118,7 +137,7 @@ jobs: mkdir -p "$release_changelog_path" cd "$release_changelog_path" # Generate the changelog entries for each updated dependency - echo "$UPDATED_DEPENDENCIES" | jq --compact-output '.[]' | while read -r dependency; do + cat "$UPDATED_DEPENDENCIES" | jq --compact-output '.[]' | while read -r dependency; do # Extract the dependency name and version dependency_name=$(echo "$dependency" | jq -r '.dependencyName') changelog_file_name=$(echo "update_${dependency_name,,}.xml" | sed -r -e 's/[^a-z0-9.-]/_/g' -e 's/_+/_/g') @@ -134,14 +153,13 @@ jobs: - name: Add & commit changes shell: bash env: - COMMIT_MSG: "Generate changelog entries for PR #${{ github.event.pull_request.number }}" - USER_NAME: ${{ inputs.user_name }} - USER_EMAIL: ${{ inputs.user_email }} + USER_NAME: ${{ inputs.user-name }} + USER_EMAIL: ${{ inputs.user-email }} run: | git add src/changelog git config user.name "$USER_NAME" git config user.email "$USER_EMAIL" - git commit -S -m "$COMMIT_MSG" + git commit -S -m "Generate changelog entries for PR #$PR_ID" git push origin - name: Enable auto-merge on PR diff --git a/src/site/antora/modules/ROOT/examples/process-dependabot.yaml b/src/site/antora/modules/ROOT/examples/analyze-dependabot.yaml similarity index 55% copy from src/site/antora/modules/ROOT/examples/process-dependabot.yaml copy to src/site/antora/modules/ROOT/examples/analyze-dependabot.yaml index 6f7d204..c4a850c 100644 --- a/src/site/antora/modules/ROOT/examples/process-dependabot.yaml +++ b/src/site/antora/modules/ROOT/examples/analyze-dependabot.yaml @@ -15,31 +15,18 @@ # limitations under the License. # -name: Dependabot Process PR +name: "Dependabot Analyze PR" on: - pull_request_target: {} + pull_request: -permissions: read-all +permissions: { } jobs: -# tag::process-dependabot[] - process-dependabot: +# tag::analyze-dependabot[] + analyze-dependabot: # Skip this workflow on commits not pushed by Dependabot if: ${{ github.actor == 'dependabot[bot]' }} - uses: apache/logging-parent/.github/workflows/process-dependabot-reusable.yaml@rel/{project-version} - permissions: - # The default GITHUB_TOKEN will be used to enable the "auto-merge" on the PR - pull-requests: write - secrets: - AUTO_MERGE_TOKEN: ${{ github.token }} - CONTENT_WRITE_TOKEN: ${{ secrets.DEPENDABOT_TOKEN }} - GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} - with: - user_name: 'Release Manager' - user_email: [email protected] - # Necessary to let the reusable workflow reference itself - reusable_ref: rel/{project-version} -# end::process-dependabot[] + uses: apache/logging-parent/.github/workflows/analyze-dependabot-reusable.yaml@rel/{project-version} +# end::analyze-dependabot[] diff --git a/src/site/antora/modules/ROOT/examples/process-dependabot.yaml b/src/site/antora/modules/ROOT/examples/process-dependabot.yaml index 6f7d204..06ac250 100644 --- a/src/site/antora/modules/ROOT/examples/process-dependabot.yaml +++ b/src/site/antora/modules/ROOT/examples/process-dependabot.yaml @@ -15,22 +15,28 @@ # limitations under the License. # -name: Dependabot Process PR +name: "Dependabot Process PR" on: - pull_request_target: {} + workflow_run: + workflows: + - "Dependabot Analyze PR" + types: + - completed -permissions: read-all +permissions: { } jobs: # tag::process-dependabot[] process-dependabot: # Skip this workflow on commits not pushed by Dependabot - if: ${{ github.actor == 'dependabot[bot]' }} + if: ${{ github.event.workflow_run.conclusion == 'success' && github.actor == 'dependabot[bot]' }} uses: apache/logging-parent/.github/workflows/process-dependabot-reusable.yaml@rel/{project-version} permissions: # The default GITHUB_TOKEN will be used to enable the "auto-merge" on the PR + # This requires the following two permissions: + contents: write pull-requests: write secrets: AUTO_MERGE_TOKEN: ${{ github.token }} @@ -38,8 +44,10 @@ jobs: GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} with: - user_name: 'Release Manager' - user_email: [email protected] - # Necessary to let the reusable workflow reference itself - reusable_ref: rel/{project-version} + # These are the default values. + # The e-mail address must match the one used in the GPG key. + user_name: "ASF Logging Services RM" + user_email: "[email protected]" + # The run ID of the workflow that analyzed the PR. + analyze-workflow-run-id: ${{ github.event.workflow_run.id }} # end::process-dependabot[] diff --git a/src/site/antora/modules/ROOT/pages/workflows.adoc b/src/site/antora/modules/ROOT/pages/workflows.adoc index 2369dd3..0aa4dfb 100644 --- a/src/site/antora/modules/ROOT/pages/workflows.adoc +++ b/src/site/antora/modules/ROOT/pages/workflows.adoc @@ -104,6 +104,25 @@ To verify the reproducibility of a release, you can use: include::example$build.yaml[tag=verify-reproducibility-release,indent=0] ---- +[#analyze-dependabot] +== {project-github-url}/blob/main/.github/workflows/analyze-dependabot-reusable.yaml[`analyze-dependabot-reusable.yaml`] + +Analyzes Dependabot pull requests to collect detailed information about updated dependencies. +Stores the results in the `dependabot-metadata` artifact, +which is later consumed by the <<process-dependabot>> workflow to automate changelog generation and PR processing. + +[NOTE] +==== +This workflow must be triggered by an event that includes the `pull_request` payload and does not require any privileges. +It can then be used in a `pull_request` workflow. +==== + +.Snippet from an {examples-base-link}/analyze-dependabot.yaml[example `analyze-dependabot.yaml`] using this workflow +[source,yaml,subs=+attributes] +---- +include::example$analyze-dependabot.yaml[tag=analyze-dependabot,indent=0] +---- + [#process-dependabot] == {project-github-url}/blob/main/.github/workflows/process-dependabot-reusable.yaml[`process-dependabot-reusable.yaml`] @@ -112,6 +131,28 @@ Helps to process Dependabot pull requests by: * Generating changelog entries for the updated dependencies. * Enabling the "auto-merge" option for the pull request. +The workflow needs the following privileged tokens: + +`AUTO_MERGE_TOKEN`:: +A GitHub token with `contents:write` and `pull_requests:write` permissions, used to enable auto-merge on pull requests. +The default `GITHUB_TOKEN` **can** be used for this purpose. + +`CONTENT_WRITE_TOKEN`:: +A GitHub token required to push generated changelog files as a new commit to the repository. +The default `GITHUB_TOKEN` can **not** be used, +as it will not trigger required check runs and will prevent the pull request from being merged. +A Personal Access Token (PAT) with `contents:write` permission must be provided instead. + +This workflow is designed to be triggered by the `workflow_run` event, +as soon as the <<analyze-dependabot>> workflow completes. + +[NOTE] +==== +When this workflow is triggered by `workflow_run`, +GitHub Actions uses the "Actions" secret context instead of "Dependabot" secrets, +even if the `github.actor` is `dependabot[bot]`. +==== + .Snippet from an {examples-base-link}/process-dependabot.yaml[example `process-dependabot.yaml`] using this workflow [source,yaml,subs=+attributes] ----
