Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
57f5ae9
feat: add `process-dependabot-reusable` workflow (Bash-based alternat…
ppkarwasz Jun 16, 2025
305af05
fix: Typos detected by Copilot
ppkarwasz Jun 22, 2025
32fe361
fix: install `xmlstarlet`
ppkarwasz Jun 22, 2025
59ea4d2
fix: replace `apt` with `apt-get`
ppkarwasz Jun 22, 2025
27bd899
feat: Split Dependabot workflow into privileged and unprivileged parts
ppkarwasz Jun 24, 2025
6f9d490
fix: limit the number of tokens
ppkarwasz Jun 24, 2025
a1f91ab
fix: drop all permissions by default
ppkarwasz Jun 24, 2025
ef0d793
Apply suggestions from code review
ppkarwasz Oct 26, 2025
da481c2
fix: switch to `dependabot/fetch-metadata`
ppkarwasz Nov 5, 2025
fbdf609
fix: apply review suggestions
ppkarwasz Nov 5, 2025
d2b0c59
fix: extract PR data from caller of `process-dependabot-reusable`
ppkarwasz Apr 14, 2026
9565410
fix: inline user-name and user-email
ppkarwasz Apr 14, 2026
f88dade
fix: add `changelog-path` and remove `xmlstarlet`
ppkarwasz Apr 14, 2026
3c86f2d
fix: sort inputs
ppkarwasz Apr 14, 2026
4fd4cf0
fix: filters on PR user
ppkarwasz Apr 14, 2026
f78eab8
fix: remove computable parameters
ppkarwasz Apr 15, 2026
a78b727
fix: refactor XML escaping
ppkarwasz Apr 15, 2026
615116f
fix: debug `workflow_run` payload
ppkarwasz Apr 15, 2026
499214f
fix: remove license line
ppkarwasz Apr 15, 2026
72e0f9c
fix: add comments to checks
ppkarwasz Apr 15, 2026
2525d34
fix: check order
ppkarwasz Apr 15, 2026
9a008db
Merge branch 'main' into feat/dependabot-add-changelog2
ppkarwasz Apr 15, 2026
928fe46
fix: adapt to `ppkarwasz` organisation
ppkarwasz Apr 15, 2026
2d9b235
Bump Dependabot workflow dependencies
dependabot[bot] Apr 15, 2026
c5d1ed3
Update Dependabot workflows dependencies
ppkarwasz Apr 15, 2026
310d069
Remove commit signing
ppkarwasz Apr 15, 2026
f6ef80d
Modify preconditions
ppkarwasz Apr 15, 2026
725cdbd
Merge branch 'feat/dependabot-add-changelog-test' into feat/dependabo…
ppkarwasz Apr 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .github/workflows/analyze-dependabot-reusable.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#
# 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: { }

# Explicitly drop all permissions inherited from the caller for security.
# Reference: https://docs.github.com/en/actions/sharing-automations/reusing-workflows#access-and-permissions
permissions: { }

jobs:

analyze-pull-request:
# Defense-in-depth (in case the caller forgets):
# `github.actor` prevents recursive calls when `github-actions[bot]` pushes to the PR;
# `github.event.pull_request.user.login` skips PRs not opened by Dependabot.
if: ${{
github.actor == 'dependabot[bot]'
&& github.event.pull_request.user.login == 'dependabot[bot]'
}}
runs-on: ubuntu-latest

steps:

- name: Fetch Dependabot metadata
id: dependabot
uses: dependabot/fetch-metadata@ffa630c65fa7e0ecfa0625b5ceda64399aea1b36 # 3.0.0
with:
github-token: ${{ github.token }}

# Creates the data required by the `process-dependabot-reusable` workflow as a JSON file.
- name: Create artifact
shell: bash
env:
UPDATED_DEPENDENCIES: ${{ steps.dependabot.outputs.updated-dependencies-json }}
run: |
echo "$UPDATED_DEPENDENCIES" > updated_dependencies.json

- name: Upload artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # 7.0.1
with:
name: dependabot-metadata
path: updated_dependencies.json
142 changes: 142 additions & 0 deletions .github/workflows/process-dependabot-reusable.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
#
# 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:
changelog-path:
description: The path to the changelog directory (e.g. `src/changelog/.2.x.x`)
required: true
type: string
secrets:
RECURSIVE_TOKEN:
description: "A PAT with `contents: write` permission to push changes and trigger the next workflow run"
required: true

# Explicitly drop all permissions inherited from the caller for security.
# Reference: https://docs.github.com/en/actions/sharing-automations/reusing-workflows#access-and-permissions
permissions: { }

jobs:

generate-changelog:
# Defense-in-depth (in case the caller forgets):
# `github.actor` prevents recursive calls when `github-actions[bot]` pushes to the PR;
# `github.event.workflow_run.conclusion` only runs after a successful analysis workflow.
if: ${{
github.actor == 'dependabot[bot]'
&& github.event.workflow_run.conclusion == 'success'
}}
runs-on: ubuntu-latest
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

steps:

- name: Get pull request metadata
id: pr
env:
# Reference of the payload: https://docs.github.com/en/webhooks/webhook-events-and-payloads#workflow_run
#
# The structure of `pull_requests` is not documented, so we'll dump it for debugging purposes.
PULL_REQUESTS: ${{ toJSON(github.event.workflow_run.pull_requests) }}
run: |
# Print payload for debugging
jq <<< "$PULL_REQUESTS"
echo "id=$(echo "$PULL_REQUESTS" | jq -r '.[0].number')" >> "$GITHUB_OUTPUT"
echo "head-ref=$(echo "$PULL_REQUESTS" | jq -r '.[0].head.ref')" >> "$GITHUB_OUTPUT"

- name: Fetch Dependabot metadata
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # 8.0.1
with:
github-token: ${{ github.token }}
name: dependabot-metadata
path: ${{ runner.temp }}
run-id: ${{ github.event.workflow_run.id }}

- name: Check out repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 6.0.2
with:
ref: ${{ steps.pr.outputs.head-ref }}
token: ${{ secrets.RECURSIVE_TOKEN }}

- name: Create changelog entries
shell: bash
env:
PR_ID: ${{ steps.pr.outputs.id }}
PR_URL: ${{ github.server_url }}/${{ github.repository }}/pull/${{ steps.pr.outputs.id }}
CHANGELOG_PATH: ${{ inputs.changelog-path }}
UPDATED_DEPENDENCIES: ${{ runner.temp }}/updated_dependencies.json
run: |
# Escapes special XML characters in a string
xml_escape() { sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g; s/"/\&quot;/g'; }

# Generates the content of a changelog entry
function generate_changelog_entry() {
local dependency="$1"
local issue_id=$(xml_escape <<< "$PR_ID")
local issue_link=$(xml_escape <<< "$PR_URL")
local dependency_name=$(echo "$dependency" | jq -r '.dependencyName' | xml_escape)
local new_version=$(echo "$dependency" | jq -r '.newVersion' | xml_escape)
cat << CHANGELOG_ENTRY
<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://logging.apache.org/xml/ns"
xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
type="updated">
<issue id="$issue_id" link="$issue_link"/>
<description format="asciidoc">Update \`$dependency_name\` to version \`$new_version\`</description>
</entry>
CHANGELOG_ENTRY
}

# Ensure the changelog directory exists
mkdir -p "$CHANGELOG_PATH"
cd "$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: Add & commit changes
shell: bash
env:
CHANGELOG_PATH: ${{ inputs.changelog-path }}
PR_ID: ${{ steps.pr.outputs.id }}
run: |
git add "$CHANGELOG_PATH"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git commit -m "Generate changelog entries for #$PR_ID"
git push origin

- name: Enable auto-merge on PR
shell: bash
env:
GH_TOKEN: ${{ github.token }}
PR_ID: ${{ steps.pr.outputs.id }}
run: |
gh pr merge --squash --auto "$PR_ID"
10 changes: 10 additions & 0 deletions src/changelog/.12.x.x/add-deploy-profile.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://logging.apache.org/xml/ns"
xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
type="added">
<issue id="417" link="https://github.com/apache/logging-parent/issues/417"/>
<description format="asciidoc">
Added `process-dependabot-reusable` to handle Dependabot PRs under RTC restrictions.
</description>
</entry>
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,23 @@
# 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:
# `github.actor` prevents recursive calls when `github-actions[bot]` pushes to the PR;
# `github.event.pull_request.user.login` skips PRs not opened by Dependabot.
if: ${{
github.repository == 'apache/logging-parent'
&& github.actor == 'dependabot[bot]'
&& github.event.pull_request.user.login == 'dependabot[bot]'
}}
uses: apache/logging-parent/.github/workflows/analyze-dependabot-reusable.yaml@rel/{project-version}
# end::analyze-dependabot[]
50 changes: 50 additions & 0 deletions src/site/antora/modules/ROOT/examples/process-dependabot.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#
# 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.repository == 'apache/logging-parent'
&& github.actor == 'dependabot[bot]'
&& github.event.workflow_run.conclusion == 'success'
}}
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 }}
with:
# The path to the changelog directory for the current development branch.
changelog-path: src/changelog/.2.x.x
# end::process-dependabot[]
60 changes: 57 additions & 3 deletions src/site/antora/modules/ROOT/pages/workflows.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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 <<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`]

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 <<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]
----
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`]
Expand Down
Loading