Skip to content
57 changes: 57 additions & 0 deletions .github/workflows/analyze-dependabot-reusable.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#
# 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:
# 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: dependabot/fetch-metadata@08eff52bf64351f401fb50d4972fa95b9f2c2d1b # 2.4.0
with:
github-token: ${{ github.token }}

# Creates 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 dependabot-metadata
echo "$PULL_REQUEST" > dependabot-metadata/pull_request.json
echo "$UPDATED_DEPENDENCIES" > dependabot-metadata/updated_dependencies.json
Comment on lines +50 to +51
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the meat of this entire reusable workflow, 2 LoC, the rest is just ceremony. I think this should consider integrating this into process-d-r, and removing analyze-d-r.

IIRC, you introduce this split for analyze-d-r needs less privileges compared to process-d-r. But the former is useless without the latter, hence, the split just inflates 2 LoC to 55 LoC, not to mention the inflation at call sites invoking these reusables.


- name: Upload artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # 4.6.2
with:
name: dependabot-metadata
path: dependabot-metadata
183 changes: 183 additions & 0 deletions .github/workflows/process-dependabot-reusable.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
#
# 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: '[email protected]'
Comment on lines +25 to +29
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we expect an occasion where these defaults will be overriden? If not, please consider inlining them. I prefer code that is 8 lines shorter compared to a functionality that we don't use.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, no! I need these parameters for now to test the workflow with a different GPG key in my fork.

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

# 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:
# Skip this workflow on commits not pushed by Dependabot
if: ${{ github.actor == 'dependabot[bot]' }}
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: 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"
Comment on lines +75 to +86
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of this can be avoided if 2 LoC moved from analyze-d-r to here.

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
Comment on lines +87 to +89
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a spec. somewhere on the JSON schema of the dependabot PR payload? If yes, sharing it here in a comment would be very useful for the next maintainer troubleshooting an issue here.


- 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: |
# Extract the revision property from the pom.xml
revision=$(
xmlstarlet sel \
-N m=http://maven.apache.org/POM/4.0.0 \
--template --value-of /m:project/m:properties/m:revision \
pom.xml
)

# Validate the version format and extract the major version
if [[ ! $revision =~ ^[0-9]+\.[0-9]+\.[0-9]+(-SNAPSHOT)?$ ]]; then
echo "Invalid version format: $revision"
exit 1
fi

revisionMajor=${revision%%.*}
echo "RELEASE_VERSION_MAJOR=$revisionMajor" >> $GITHUB_ENV

- name: Create changelog entries
shell: bash
run: |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd really appreciate it if you can ventilate this big chunk of code with some empty lines delimiting the blocks by their semantics.

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
<?xml version="1.0" encoding="UTF-8"?>
<!-- SPDX-License-Identifier: Apache-2.0 -->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, Logging Services speak CDX, not SPDX. I think we should discuss this with the rest of the crew and introduce it in a mass roll out instead of piggybacking.

Suggested change
<!-- SPDX-License-Identifier: Apache-2.0 -->
<!-- SPDX-License-Identifier: Apache-2.0 -->

<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
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_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"
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,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.repository == 'apache/logging-parent' && github.actor == 'dependabot[bot]' }}
uses: apache/logging-parent/.github/workflows/analyze-dependabot-reusable.yaml@rel/{project-version}
# end::analyze-dependabot[]
52 changes: 52 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,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]' }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I'd keep the repository name validation.

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: "[email protected]"
# The run ID of the workflow that analyzed the PR.
analyze-workflow-run-id: ${{ github.event.workflow_run.id }}
# end::process-dependabot[]
Loading
Loading