diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 179d9eab..f73d7c42 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -36,3 +36,4 @@ But you might still need to adapt your code: - Added a migration step for api repositories to fix `mkdocs.yml` when the previous `mkdocstrings-python` v2 migration moved only `paths: ["src"]` under `handlers.python.options` but not `paths: ["py"]`. - Fixed runners for jobs that require Docker and where wrongly converted to `ubuntu-slim` in v0.15.0, changing them back to `ubuntu-24.04` to avoid Docker-related failures. The template and the migration script were both updated to reflect this change. +- Updated the repo-config migration workflow template and migration script so existing repositories also add the `merge_group` trigger and skip the job unless the event is `pull_request_target`, allowing the workflow to be used as a required merge-queue check. diff --git a/cookiecutter/migrate.py b/cookiecutter/migrate.py index bc25db29..03f050db 100644 --- a/cookiecutter/migrate.py +++ b/cookiecutter/migrate.py @@ -38,6 +38,9 @@ def main() -> None: """Run the migration steps.""" # Add a separation line like this one after each migration step. print("=" * 72) + print("Fixing repo-config migration merge queue trigger...") + migrate_repo_config_migration_merge_group_trigger() + print("=" * 72) print("Fixing mkdocstrings-python v2 paths for api repos...") migrate_api_mkdocs_mkdocstrings_paths() print("=" * 72) @@ -233,6 +236,73 @@ def migrate_docker_based_runners() -> None: ) +def migrate_repo_config_migration_merge_group_trigger() -> None: + """Trigger repo-config migration in the merge queue.""" + filepath = Path(".github/workflows/repo-config-migration.yaml") + if not filepath.exists(): + manual_step( + "Unable to find .github/workflows/repo-config-migration.yaml; if this " + "project uses the repo-config migration workflow, update it to trigger " + "on `merge_group` and skip the job unless the event is " + "`pull_request_target`." + ) + return + + content = filepath.read_text(encoding="utf-8") + old_on = ( + "on:\n" + " pull_request_target:\n" + " types: [opened, synchronize, reopened, labeled, unlabeled]\n" + ) + new_on = ( + "on:\n" + " merge_group: # To allow using this as a required check for merging\n" + " pull_request_target:\n" + " types: [opened, synchronize, reopened, labeled, unlabeled]\n" + ) + old_if = ( + " if: contains(github.event.pull_request.title, 'the repo-config group')" + ) + new_if = ( + " # Skip if it was triggered by the merge queue. We only need the workflow to\n" + ' # be executed to meet the "Required check" condition for merging, but we\n' + " # don't need to actually run the job, having the job present as Skipped is\n" + " # enough.\n" + " if: |\n" + " github.event_name == 'pull_request_target' &&\n" + " contains(github.event.pull_request.title, 'the repo-config group')" + ) + + updated = content + if old_on in updated: + updated = updated.replace(old_on, new_on, 1) + + if old_if in updated: + updated = updated.replace(old_if, new_if, 1) + + if updated != content: + replace_file_atomically(filepath, updated) + print( + " Updated .github/workflows/repo-config-migration.yaml: added " + "merge_group trigger" + ) + return + + if new_on in content and new_if in content: + print( + " Skipped .github/workflows/repo-config-migration.yaml: merge queue " + "trigger already configured" + ) + return + + manual_step( + "Could not find the expected repo-config migration workflow pattern in " + ".github/workflows/repo-config-migration.yaml. If this repository uses " + "that workflow, add the `merge_group` trigger and make the job run only " + "for `pull_request_target` events according to the latest template." + ) + + def apply_patch(patch_content: str) -> None: """Apply a patch using the patch utility.""" subprocess.run(["patch", "-p1"], input=patch_content.encode(), check=True) diff --git a/cookiecutter/{{cookiecutter.github_repo_name}}/.github/workflows/repo-config-migration.yaml b/cookiecutter/{{cookiecutter.github_repo_name}}/.github/workflows/repo-config-migration.yaml index 9b6101c4..306828b1 100644 --- a/cookiecutter/{{cookiecutter.github_repo_name}}/.github/workflows/repo-config-migration.yaml +++ b/cookiecutter/{{cookiecutter.github_repo_name}}/.github/workflows/repo-config-migration.yaml @@ -20,6 +20,7 @@ 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] @@ -31,7 +32,13 @@ permissions: jobs: repo-config-migration: name: Migrate Repo Config - if: contains(github.event.pull_request.title, 'the repo-config group') + # 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 diff --git a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/workflows/repo-config-migration.yaml b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/workflows/repo-config-migration.yaml index c2d3d489..57a54c32 100644 --- a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/workflows/repo-config-migration.yaml +++ b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/.github/workflows/repo-config-migration.yaml @@ -19,6 +19,7 @@ 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] @@ -30,7 +31,13 @@ permissions: jobs: repo-config-migration: name: Migrate Repo Config - if: contains(github.event.pull_request.title, 'the repo-config group') + # 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 diff --git a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/workflows/repo-config-migration.yaml b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/workflows/repo-config-migration.yaml index c2d3d489..57a54c32 100644 --- a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/workflows/repo-config-migration.yaml +++ b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/.github/workflows/repo-config-migration.yaml @@ -19,6 +19,7 @@ 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] @@ -30,7 +31,13 @@ permissions: jobs: repo-config-migration: name: Migrate Repo Config - if: contains(github.event.pull_request.title, 'the repo-config group') + # 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 diff --git a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/workflows/repo-config-migration.yaml b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/workflows/repo-config-migration.yaml index c2d3d489..57a54c32 100644 --- a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/workflows/repo-config-migration.yaml +++ b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/.github/workflows/repo-config-migration.yaml @@ -19,6 +19,7 @@ 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] @@ -30,7 +31,13 @@ permissions: jobs: repo-config-migration: name: Migrate Repo Config - if: contains(github.event.pull_request.title, 'the repo-config group') + # 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 diff --git a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/workflows/repo-config-migration.yaml b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/workflows/repo-config-migration.yaml index c2d3d489..57a54c32 100644 --- a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/workflows/repo-config-migration.yaml +++ b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/.github/workflows/repo-config-migration.yaml @@ -19,6 +19,7 @@ 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] @@ -30,7 +31,13 @@ permissions: jobs: repo-config-migration: name: Migrate Repo Config - if: contains(github.event.pull_request.title, 'the repo-config group') + # 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 diff --git a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/workflows/repo-config-migration.yaml b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/workflows/repo-config-migration.yaml index c2d3d489..57a54c32 100644 --- a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/workflows/repo-config-migration.yaml +++ b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/.github/workflows/repo-config-migration.yaml @@ -19,6 +19,7 @@ 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] @@ -30,7 +31,13 @@ permissions: jobs: repo-config-migration: name: Migrate Repo Config - if: contains(github.event.pull_request.title, 'the repo-config group') + # 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