diff --git a/.github/workflows/analyze-dependabot-reusable.yaml b/.github/workflows/analyze-dependabot-reusable.yaml
new file mode 100644
index 00000000..a23fad51
--- /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
new file mode 100644
index 00000000..e2b18c9d
--- /dev/null
+++ b/.github/workflows/process-dependabot-reusable.yaml
@@ -0,0 +1,169 @@
+#
+# 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 Process PR
+
+on:
+ workflow_call:
+ inputs:
+ user-name:
+ description: The name of the user to use for the commit
+ default: 'ASF Logging Services RM'
+ type: string
+ user-email:
+ description: The email of the user to use for the commit
+ default: 'private@logging.apache.org'
+ type: string
+ analyze-workflow-run-id:
+ description: The ID of the workflow run that analyzed the PR
+ required: true
+ type: number
+ secrets:
+ RECURSIVE_TOKEN:
+ description: "A PAT with `contents: write` permission to push changes and trigger the next workflow run"
+ required: true
+ GPG_PASSPHRASE:
+ description: GPG passphrase for signing commits
+ required: false
+ GPG_PRIVATE_KEY:
+ description: GPG secret key for signing commits
+ required: true
+
+permissions: { }
+
+jobs:
+
+ generate-changelog:
+ # Skip this workflow on commits not pushed by Dependabot
+ if: ${{ github.actor == 'dependabot[bot]' }}
+ runs-on: ubuntu-latest
+
+ steps:
+
+ - name: Fetch Dependabot metadata
+ 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: ${{ env.PR_HEAD_REF }}
+ token: ${{ secrets.RECURSIVE_TOKEN }}
+
+ - name: Install `xmlstarlet`
+ shell: bash
+ run: sudo apt-get update && sudo apt-get install -y xmlstarlet
+
+ - name: Find the release version major
+ shell: bash
+ run: |
+ revision=$(
+ xmlstarlet sel \
+ -N m=http://maven.apache.org/POM/4.0.0 \
+ --template --value-of /m:project/m:properties/m:revision \
+ pom.xml
+ )
+ if [[ ! $revision =~ ^[0-9]+\.[0-9]+\.[0-9]+(-SNAPSHOT)?$ ]]; then
+ echo "Invalid version format: $revision"
+ exit 1
+ fi
+ parts=(${revision//./ })
+ echo "RELEASE_VERSION_MAJOR=${parts[0]}" >> $GITHUB_ENV
+
+ - name: Create changelog entries
+ shell: bash
+ 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 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
+
+
+
+
+ Update \`$dependency_name\` to version \`$new_version\`.
+
+ CHANGELOG_ENTRY
+ }
+ # Ensure the changelog directory exists
+ release_changelog_path="src/changelog/.${RELEASE_VERSION_MAJOR}.x.x"
+ mkdir -p "$release_changelog_path"
+ cd "$release_changelog_path"
+ # Generate the changelog entries for each updated dependency
+ 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')
+ generate_changelog_entry "$dependency" > "$changelog_file_name"
+ done
+
+ - name: Set up GPG
+ uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # 6.3.0
+ with:
+ gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
+ passphrase: ${{ secrets.GPG_PASSPHRASE }}
+
+ - name: Add & commit changes
+ shell: bash
+ env:
+ 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 "Generate changelog entries for PR #$PR_ID"
+ git push origin
+
+ - name: Enable auto-merge on PR
+ shell: bash
+ env:
+ GH_TOKEN: ${{ github.token }}
+ run: |
+ gh pr merge --squash --auto "$PR_URL"
diff --git a/src/changelog/.12.x.x/add-deploy-profile.xml b/src/changelog/.12.x.x/add-deploy-profile.xml
new file mode 100644
index 00000000..a34fffff
--- /dev/null
+++ b/src/changelog/.12.x.x/add-deploy-profile.xml
@@ -0,0 +1,10 @@
+
+
+
+
+ Added `process-dependabot-reusable` to handle Dependabot PRs under RTC restrictions.
+
+
diff --git a/.github/workflows/merge-dependabot.yaml b/src/site/antora/modules/ROOT/examples/analyze-dependabot.yaml
similarity index 52%
rename from .github/workflows/merge-dependabot.yaml
rename to src/site/antora/modules/ROOT/examples/analyze-dependabot.yaml
index 2d611cc1..c4a850c7 100644
--- a/.github/workflows/merge-dependabot.yaml
+++ b/src/site/antora/modules/ROOT/examples/analyze-dependabot.yaml
@@ -15,28 +15,18 @@
# limitations under the License.
#
-name: merge-dependabot
+name: "Dependabot Analyze PR"
on:
- pull_request_target:
- paths-ignore:
- - "**.adoc"
- - "**.md"
- - "**.txt"
+ pull_request:
-permissions: read-all
+permissions: { }
jobs:
- build:
- if: github.repository == 'apache/logging-parent' && github.event_name == 'pull_request_target' && github.actor == 'dependabot[bot]'
- uses: ./.github/workflows/build-reusable.yaml
-
- merge-dependabot:
- needs: build
- uses: ./.github/workflows/merge-dependabot-reusable.yaml
- permissions:
- contents: write # to push changelog commits
- pull-requests: write # to close the PR
- secrets:
- GPG_SECRET_KEY: ${{ secrets.LOGGING_GPG_SECRET_KEY }} # to sign commits
+# 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/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
new file mode 100644
index 00000000..16503cab
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/process-dependabot.yaml
@@ -0,0 +1,52 @@
+#
+# 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 Process PR"
+
+on:
+ workflow_run:
+ workflows:
+ - "Dependabot Analyze PR"
+ types:
+ - completed
+
+permissions: { }
+
+jobs:
+
+# tag::process-dependabot[]
+ process-dependabot:
+ # Skip this workflow on commits not pushed by Dependabot
+ 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:
+ RECURSIVE_TOKEN: ${{ secrets.DEPENDABOT_TOKEN }}
+ GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
+ GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
+ with:
+ # 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: "private@logging.apache.org"
+ # 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 e9ed9f90..62c64ca2 100644
--- a/src/site/antora/modules/ROOT/pages/workflows.adoc
+++ b/src/site/antora/modules/ROOT/pages/workflows.adoc
@@ -104,10 +104,64 @@ To verify the reproducibility of a release, you can use:
include::example$build.yaml[tag=verify-reproducibility-release,indent=0]
----
-[#merge-dependabot]
-== {project-github-url}/blob/main/.github/workflows/merge-dependabot-reusable.yaml[`merge-dependabot-reusable.yaml`]
+[#analyze-dependabot]
+== {project-github-url}/blob/main/.github/workflows/analyze-dependabot-reusable.yaml[`analyze-dependabot-reusable.yaml`]
-Merges Dependabot PRs along with changelog entries.
+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 <> 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`]
+
+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:
+
+`GITHUB_TOKEN`::
+The default GitHub token with `contents:write` and `pull_requests:write` permissions,
+used to enable auto-merge on pull requests.
++
+This token is automatically provided by GitHub Actions, but needs to be configured in the `permissions` property.
+
+`RECURSIVE_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.
++
+The token must be passed as a secret named `RECURSIVE_TOKEN`.
+
+This workflow is designed to be triggered by the `workflow_run` event,
+as soon as the <> 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]
+----
+include::example$process-dependabot.yaml[tag=process-dependabot,indent=0]
+----
[#deploy-site]
== {project-github-url}/blob/main/.github/workflows/deploy-site-reusable.yaml[`deploy-site-reusable.yaml`]