Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 8 additions & 2 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,28 @@ updates:
- "minor"
exclude-patterns:
- "async-solipsism"
- "frequenz-repo-config*"
- "frequenz-repo-config"
- "frequenz-repo-config[lib]"
- "frequenz-repo-config[extra-lint-examples]"
- "markdown-callouts"
- "mkdocs-gen-files"
- "mkdocs-literate-nav"
- "mkdocstrings*"
- "mkdocstrings[python]"
- "pydoclint"
- "pytest-asyncio"
# We group repo-config updates as it uses optional dependencies that are
# considered different dependencies otherwise, and will create one PR for
# each if we don't group them.
repo-config:
patterns:
- "frequenz-repo-config*"
- "frequenz-repo-config"
- "frequenz-repo-config[lib]"
- "frequenz-repo-config[extra-lint-examples]"
mkdocstrings:
patterns:
- "mkdocstrings*"
- "mkdocstrings[python]"

- package-ecosystem: "github-actions"
directory: "/"
Expand Down
60 changes: 60 additions & 0 deletions .github/workflows/repo-config-migration.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Automatic repo-config migrations for Dependabot PRs
#
# The companion auto-dependabot workflow skips repo-config group PRs so
# they're handled exclusively by the migration workflow.
Comment on lines +3 to +4
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

The header comment says the companion auto-dependabot workflow “skips repo-config group PRs”, but .github/workflows/auto-dependabot.yaml currently runs for all Dependabot PRs (dependency-type: 'all') with no title/group-based skip. Please either update the comment to match reality, or adjust the companion workflow so repo-config group PRs are actually excluded if that exclusivity is required.

Suggested change
# The companion auto-dependabot workflow skips repo-config group PRs so
# they're handled exclusively by the migration workflow.
# This workflow runs migrations for Dependabot PRs that update the
# repo-config group.

Copilot uses AI. Check for mistakes.
#
# XXX: !!! SECURITY WARNING !!!
# pull_request_target has write access to the repo, and can read secrets.
# This is required because Dependabot PRs are treated as fork PRs: the
# GITHUB_TOKEN is read-only and secrets are unavailable with a plain
# pull_request trigger. The action mitigates the risk by:
# - Never executing code from the PR (migrate.py is fetched from an
# upstream tag, not from the checked-out branch).
# - Gating migration steps on github.actor == 'dependabot[bot]'.
# - Running checkout with persist-credentials: false and isolating
# push credentials from the migration script environment.
# For more details read:
# https://securitylab.github.com/research/github-actions-preventing-pwn-requests/

name: Repo Config Migration

on:
merge_group: # To allow using this as a required check for merging
pull_request_target:
types: [opened, synchronize, reopened, labeled, unlabeled]

permissions:
contents: write
issues: write
pull-requests: write

jobs:
repo-config-migration:
name: Migrate Repo Config
# Skip if it was triggered by the merge queue. We only need the workflow to
# be executed to meet the "Required check" condition for merging, but we
# don't need to actually run the job, having the job present as Skipped is
# enough.
if: |
github.event_name == 'pull_request_target' &&
contains(github.event.pull_request.title, 'the repo-config group')
runs-on: ubuntu-24.04
steps:
- name: Generate token
id: create-app-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
with:
app-id: ${{ secrets.FREQUENZ_AUTO_DEPENDABOT_APP_ID }}
private-key: ${{ secrets.FREQUENZ_AUTO_DEPENDABOT_APP_PRIVATE_KEY }}
Comment on lines +38 to +48
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

Security: this workflow runs on pull_request_target and immediately generates a GitHub App token from secrets, but the job-level if only checks the PR title. Any external contributor could open a PR with a matching title and trigger this job, exposing a high-privilege token to an untrusted context (even if no PR code is checked out). Tighten the gating to ensure the PR itself was created by Dependabot (e.g., github.event.pull_request.user.login == 'dependabot[bot]', and optionally also validate head.ref/head.repo.full_name) before generating tokens or running the migrate action; also update the header comment that claims gating on github.actor to reflect the actual condition needed for labeled/unlabeled events.

Copilot uses AI. Check for mistakes.
- name: Migrate
Comment on lines +34 to +49
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

The job is entirely skipped for merge_group events (if: github.event_name == 'pull_request_target' ...). If this workflow is configured as a required check for the merge queue, a skipped job may not satisfy branch protection/merge queue requirements. In this repo, release-notes-check.yml handles merge_group by running the job but conditionally skipping the step (job still concludes success). Consider a similar pattern here: let the job run on merge_group and short-circuit with a no-op success step, while keeping the migration steps gated to pull_request_target + Dependabot PRs.

Suggested change
# Skip if it was triggered by the merge queue. We only need the workflow to
# be executed to meet the "Required check" condition for merging, but we
# don't need to actually run the job, having the job present as Skipped is
# enough.
if: |
github.event_name == 'pull_request_target' &&
contains(github.event.pull_request.title, 'the repo-config group')
runs-on: ubuntu-24.04
steps:
- name: Generate token
id: create-app-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
with:
app-id: ${{ secrets.FREQUENZ_AUTO_DEPENDABOT_APP_ID }}
private-key: ${{ secrets.FREQUENZ_AUTO_DEPENDABOT_APP_PRIVATE_KEY }}
- name: Migrate
# Run for both pull_request_target and merge_group events. For merge_group
# we only need the job to complete successfully as a required check; the
# actual migration steps remain gated to pull_request_target events for
# repo-config group Dependabot PRs.
runs-on: ubuntu-24.04
steps:
- name: No-op for merge queue
if: github.event_name == 'merge_group'
run: echo "Merge queue run: skipping repo-config migration steps."
- name: Generate token
if: |
github.event_name == 'pull_request_target' &&
contains(github.event.pull_request.title, 'the repo-config group')
id: create-app-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
with:
app-id: ${{ secrets.FREQUENZ_AUTO_DEPENDABOT_APP_ID }}
private-key: ${{ secrets.FREQUENZ_AUTO_DEPENDABOT_APP_PRIVATE_KEY }}
- name: Migrate
if: |
github.event_name == 'pull_request_target' &&
contains(github.event.pull_request.title, 'the repo-config group')

Copilot uses AI. Check for mistakes.
uses: frequenz-floss/gh-action-dependabot-migrate@07dc7e74726498c50726a80cc2167a04d896508f # v1.0.0
with:
script-url-template: >-
https://raw.githubusercontent.com/frequenz-floss/frequenz-repo-config-python/{version}/cookiecutter/migrate.py
token: ${{ steps.create-app-token.outputs.token }}
migration-token: ${{ secrets.REPO_CONFIG_MIGRATION_TOKEN }}
sign-commits: "true"
auto-merged-label: "tool:auto-merged"
migrated-label: "tool:repo-config:migration:executed"
intervention-pending-label: "tool:repo-config:migration:intervention-pending"
intervention-done-label: "tool:repo-config:migration:intervention-done"
Loading