diff --git a/Library/Homebrew/dev-cmd/pr-automerge.rb b/Library/Homebrew/dev-cmd/pr-automerge.rb index ce5c442c81248..04c92ec374a26 100644 --- a/Library/Homebrew/dev-cmd/pr-automerge.rb +++ b/Library/Homebrew/dev-cmd/pr-automerge.rb @@ -23,11 +23,14 @@ def pr_automerge_args description: "Pull requests must have this label." comma_array "--without-labels", description: "Pull requests must not have these labels (default: " \ - "`do not merge`, `new formula`, `automerge-skip`)." + "`do not merge`, `new formula`, `automerge-skip`, `CI-published-bottle-commits`)." switch "--without-approval", description: "Pull requests do not require approval to be merged." switch "--publish", description: "Run `brew pr-publish` on matching pull requests." + switch "--autosquash", + description: "Instruct `brew pr-publish` to automatically reformat and reword commits " \ + "in the pull request to the preferred format." switch "--no-autosquash", description: "Instruct `brew pr-publish` to skip automatically reformatting and rewording commits " \ "in the pull request to the preferred format." @@ -41,10 +44,13 @@ def pr_automerge_args def pr_automerge args = pr_automerge_args.parse + odeprecated "`brew pr-publish --no-autosquash`" if args.no_autosquash? + without_labels = args.without_labels || [ "do not merge", "new formula", "automerge-skip", + "CI-published-bottle-commits", ] tap = Tap.fetch(args.tap || CoreTap.instance.name) @@ -68,10 +74,10 @@ def pr_automerge pr_urls << pr["html_url"] end - publish_args = ["pr-publish"] + publish_args = ["pr-publish", "--commit-bottles-to-pr-branch"] publish_args << "--tap=#{tap}" if tap publish_args << "--workflow=#{args.workflow}" if args.workflow - publish_args << "--no-autosquash" if args.no_autosquash? + publish_args << "--autosquash" if args.autosquash? if args.publish? safe_system HOMEBREW_BREW_FILE, *publish_args, *pr_urls else diff --git a/Library/Homebrew/dev-cmd/pr-publish.rb b/Library/Homebrew/dev-cmd/pr-publish.rb index 67731af12b2f2..1655121f5f3fe 100644 --- a/Library/Homebrew/dev-cmd/pr-publish.rb +++ b/Library/Homebrew/dev-cmd/pr-publish.rb @@ -16,20 +16,26 @@ def pr_publish_args Publish bottles for a pull request with GitHub Actions. Requires write access to the repository. EOS + switch "--commit-bottles-to-pr-branch", + description: "Push bottle commits to the pull request branch." + switch "--autosquash", + description: "If supported on the target tap, automatically reformat and reword commits " \ + "to our preferred format." switch "--no-autosquash", description: "Skip automatically reformatting and rewording commits in the pull request " \ "to the preferred format, even if supported on the target tap." + switch "--large-runner", + description: "Run the upload job on a large runner." flag "--branch=", - description: "Branch to publish to (default: `master`)." + description: "Branch to use the workflow from (default: `master`)." flag "--message=", + depends_on: "--autosquash", description: "Message to include when autosquashing revision bumps, deletions, and rebuilds." flag "--tap=", description: "Target tap repository (default: `homebrew/core`)." flag "--workflow=", description: "Target workflow filename (default: `publish-commit-bottles.yml`)." - conflicts "--no-autosquash", "--message" - named_args :pull_request, min: 1 end end @@ -37,26 +43,39 @@ def pr_publish_args def pr_publish args = pr_publish_args.parse + odeprecated "`brew pr-publish --no-autosquash`" if args.no_autosquash? + tap = Tap.fetch(args.tap || CoreTap.instance.name) workflow = args.workflow || "publish-commit-bottles.yml" ref = args.branch || "master" - extra_args = [] - extra_args << "--no-autosquash" if args.no_autosquash? - extra_args << "--message='#{args.message}'" if args.message.presence - dispatch_args = extra_args.join " " + inputs = { + commit_bottles_to_pr_branch: args.commit_bottles_to_pr_branch?, + autosquash: args.autosquash?, + large_runner: args.large_runner?, + } + inputs[:message] = args.message if args.message.presence args.named.uniq.each do |arg| arg = "#{tap.default_remote}/pull/#{arg}" if arg.to_i.positive? url_match = arg.match HOMEBREW_PULL_OR_COMMIT_URL_REGEX _, user, repo, issue = *url_match odie "Not a GitHub pull request: #{arg}" unless issue + + inputs[:pull_request] = issue + + pr_labels = GitHub.pull_request_labels(user, repo, issue) + if pr_labels.include?("autosquash") + oh1 "Found `autosquash` label on ##{issue}. Requesting autosquash." + inputs[:autosquash] = true + end + if args.tap.present? && !T.must("#{user}/#{repo}".casecmp(tap.full_name)).zero? odie "Pull request URL is for #{user}/#{repo} but `--tap=#{tap.full_name}` was specified!" end ohai "Dispatching #{tap} pull request ##{issue}" - GitHub.workflow_dispatch_event(user, repo, workflow, ref, pull_request: issue, args: dispatch_args) + GitHub.workflow_dispatch_event(user, repo, workflow, ref, inputs) end end end diff --git a/Library/Homebrew/dev-cmd/pr-pull.rb b/Library/Homebrew/dev-cmd/pr-pull.rb index 5bf66cbabb523..f37f993463745 100644 --- a/Library/Homebrew/dev-cmd/pr-pull.rb +++ b/Library/Homebrew/dev-cmd/pr-pull.rb @@ -27,11 +27,13 @@ def self.pr_pull_args switch "-n", "--dry-run", description: "Print what would be done rather than doing it." switch "--clean", - depends_on: "--no-autosquash", description: "Do not amend the commits from pull requests." switch "--keep-old", description: "If the formula specifies a rebuild version, " \ "attempt to preserve its value in the generated DSL." + switch "--autosquash", + description: "Automatically reformat and reword commits in the pull request to our " \ + "preferred format." switch "--no-autosquash", description: "Skip automatically reformatting and rewording commits in the pull request to our " \ "preferred format." @@ -46,6 +48,7 @@ def self.pr_pull_args flag "--committer=", description: "Specify a committer name and email in `git`'s standard author format." flag "--message=", + depends_on: "--autosquash", description: "Message to include when autosquashing revision bumps, deletions, and rebuilds." flag "--artifact=", description: "Download artifacts with the specified name (default: `bottles`)." @@ -62,7 +65,7 @@ def self.pr_pull_args comma_array "--ignore-missing-artifacts", description: "Comma-separated list of workflows which can be ignored if they have not been run." - conflicts "--no-autosquash", "--message" + conflicts "--clean", "--autosquash" named_args :pull_request, min: 1 end @@ -223,7 +226,8 @@ def self.squash_package_commits(commits, file, reason: "", verbose: false, resol ohai bump_subject end - def self.autosquash!(original_commit, tap:, reason: "", verbose: false, resolve: false) + # TODO: fix test in `test/dev-cmd/pr-pull_spec.rb` and assume `cherry_picked: false`. + def self.autosquash!(original_commit, tap:, reason: "", verbose: false, resolve: false, cherry_picked: true) original_head = tap.path.git_head commits = Utils.safe_popen_read("git", "-C", tap.path, "rev-list", @@ -282,9 +286,9 @@ def self.autosquash!(original_commit, tap:, reason: "", verbose: false, resolve: end end rescue - opoo "Autosquash encountered an error; resetting to original cherry-picked state at #{original_head}" + opoo "Autosquash encountered an error; resetting to original state at #{original_head}" system "git", "-C", tap.path, "reset", "--hard", original_head - system "git", "-C", tap.path, "cherry-pick", "--abort" + system "git", "-C", tap.path, "cherry-pick", "--abort" if cherry_picked raise end @@ -304,11 +308,9 @@ def self.cherry_pick_pr!(user, repo, pull_request, args:, path: ".") Utils::Git.cherry_pick!(path, "--ff", "--allow-empty", *commits, verbose: args.verbose?, resolve: args.resolve?) end - def self.formulae_need_bottles?(tap, original_commit, user, repo, pull_request, args:) + def self.formulae_need_bottles?(tap, original_commit, labels, args:) return if args.dry_run? - labels = GitHub.pull_request_labels(user, repo, pull_request) - return false if labels.include?("CI-syntax-only") || labels.include?("CI-no-bottles") changed_packages(tap, original_commit).any? do |f| @@ -424,6 +426,8 @@ def self.pr_check_conflicts(repo, pull_request) def self.pr_pull args = pr_pull_args.parse + odeprecated "`brew pr-pull --no-autosquash`" if args.no_autosquash? + # Needed when extracting the CI artifact. ensure_executable!("unzip", reason: "extracting CI artifacts") @@ -450,6 +454,11 @@ def self.pr_pull opoo "Current branch is #{tap.path.git_branch}: do you need to pull inside #{tap.path.git_origin_branch}?" end + pr_labels = GitHub.pull_request_labels(user, repo, pr) + if pr_labels.include?("autosquash") && !args.autosquash? + opoo "Pull request is labelled `autosquash`: do you need to pass `--autosquash`?" + end + pr_check_conflicts("#{user}/#{repo}", pr) ohai "Fetching #{tap} pull request ##{pr}" @@ -462,17 +471,18 @@ def self.pr_pull else current_branch_head end + odebug "Pull request merge-base: #{original_commit}" unless args.no_commit? cherry_pick_pr!(user, repo, pr, path: tap.path, args: args) unless args.no_cherry_pick? - if !args.no_autosquash? && !args.dry_run? - autosquash!(original_commit, tap: tap, + if args.autosquash? && !args.dry_run? + autosquash!(original_commit, tap: tap, cherry_picked: !args.no_cherry_pick?, verbose: args.verbose?, resolve: args.resolve?, reason: args.message) end signoff!(tap.path, pull_request: pr, dry_run: args.dry_run?) unless args.clean? end - unless formulae_need_bottles?(tap, original_commit, user, repo, pr, args: args) + unless formulae_need_bottles?(tap, original_commit, pr_labels, args: args) ohai "Skipping artifacts for ##{pr} as the formulae don't need bottles" next end diff --git a/completions/bash/brew b/completions/bash/brew index 75de306c45164..bbed1861db1c9 100644 --- a/completions/bash/brew +++ b/completions/bash/brew @@ -1661,6 +1661,7 @@ _brew_pr_automerge() { case "${cur}" in -*) __brewcomp " + --autosquash --debug --help --ignore-failures @@ -1685,9 +1686,12 @@ _brew_pr_publish() { case "${cur}" in -*) __brewcomp " + --autosquash --branch + --commit-bottles-to-pr-branch --debug --help + --large-runner --message --no-autosquash --quiet @@ -1707,6 +1711,7 @@ _brew_pr_pull() { -*) __brewcomp " --artifact + --autosquash --branch-okay --clean --committer diff --git a/completions/fish/brew.fish b/completions/fish/brew.fish index 7d356fdb41ea9..e49c114d11f5b 100644 --- a/completions/fish/brew.fish +++ b/completions/fish/brew.fish @@ -1142,6 +1142,7 @@ __fish_brew_complete_arg 'postinstall' -a '(__fish_brew_suggest_formulae_install __fish_brew_complete_cmd 'pr-automerge' 'Find pull requests that can be automatically merged using `brew pr-publish`' +__fish_brew_complete_arg 'pr-automerge' -l autosquash -d 'Instruct `brew pr-publish` to automatically reformat and reword commits in the pull request to the preferred format' __fish_brew_complete_arg 'pr-automerge' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'pr-automerge' -l help -d 'Show this message' __fish_brew_complete_arg 'pr-automerge' -l ignore-failures -d 'Include pull requests that have failing status checks' @@ -1152,14 +1153,17 @@ __fish_brew_complete_arg 'pr-automerge' -l tap -d 'Target tap repository (defaul __fish_brew_complete_arg 'pr-automerge' -l verbose -d 'Make some output more verbose' __fish_brew_complete_arg 'pr-automerge' -l with-label -d 'Pull requests must have this label' __fish_brew_complete_arg 'pr-automerge' -l without-approval -d 'Pull requests do not require approval to be merged' -__fish_brew_complete_arg 'pr-automerge' -l without-labels -d 'Pull requests must not have these labels (default: `do not merge`, `new formula`, `automerge-skip`)' +__fish_brew_complete_arg 'pr-automerge' -l without-labels -d 'Pull requests must not have these labels (default: `do not merge`, `new formula`, `automerge-skip`, `CI-published-bottle-commits`)' __fish_brew_complete_arg 'pr-automerge' -l workflow -d 'Workflow file to use with `brew pr-publish`' __fish_brew_complete_cmd 'pr-publish' 'Publish bottles for a pull request with GitHub Actions' -__fish_brew_complete_arg 'pr-publish' -l branch -d 'Branch to publish to (default: `master`)' +__fish_brew_complete_arg 'pr-publish' -l autosquash -d 'If supported on the target tap, automatically reformat and reword commits to our preferred format' +__fish_brew_complete_arg 'pr-publish' -l branch -d 'Branch to use the workflow from (default: `master`)' +__fish_brew_complete_arg 'pr-publish' -l commit-bottles-to-pr-branch -d 'Push bottle commits to the pull request branch' __fish_brew_complete_arg 'pr-publish' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'pr-publish' -l help -d 'Show this message' +__fish_brew_complete_arg 'pr-publish' -l large-runner -d 'Run the upload job on a large runner' __fish_brew_complete_arg 'pr-publish' -l message -d 'Message to include when autosquashing revision bumps, deletions, and rebuilds' __fish_brew_complete_arg 'pr-publish' -l no-autosquash -d 'Skip automatically reformatting and rewording commits in the pull request to the preferred format, even if supported on the target tap' __fish_brew_complete_arg 'pr-publish' -l quiet -d 'Make some output more quiet' @@ -1170,6 +1174,7 @@ __fish_brew_complete_arg 'pr-publish' -l workflow -d 'Target workflow filename ( __fish_brew_complete_cmd 'pr-pull' 'Download and publish bottles, and apply the bottle commit from a pull request with artifacts generated by GitHub Actions' __fish_brew_complete_arg 'pr-pull' -l artifact -d 'Download artifacts with the specified name (default: `bottles`)' +__fish_brew_complete_arg 'pr-pull' -l autosquash -d 'Automatically reformat and reword commits in the pull request to our preferred format' __fish_brew_complete_arg 'pr-pull' -l branch-okay -d 'Do not warn if pulling to a branch besides the repository default (useful for testing)' __fish_brew_complete_arg 'pr-pull' -l clean -d 'Do not amend the commits from pull requests' __fish_brew_complete_arg 'pr-pull' -l committer -d 'Specify a committer name and email in `git`\'s standard author format' diff --git a/completions/zsh/_brew b/completions/zsh/_brew index b1f72effb8514..bae3bd9485386 100644 --- a/completions/zsh/_brew +++ b/completions/zsh/_brew @@ -1403,6 +1403,7 @@ _brew_postinstall() { # brew pr-automerge _brew_pr_automerge() { _arguments \ + '--autosquash[Instruct `brew pr-publish` to automatically reformat and reword commits in the pull request to the preferred format]' \ '--debug[Display any debugging information]' \ '--help[Show this message]' \ '--ignore-failures[Include pull requests that have failing status checks]' \ @@ -1413,18 +1414,21 @@ _brew_pr_automerge() { '--verbose[Make some output more verbose]' \ '--with-label[Pull requests must have this label]' \ '--without-approval[Pull requests do not require approval to be merged]' \ - '--without-labels[Pull requests must not have these labels (default: `do not merge`, `new formula`, `automerge-skip`)]' \ + '--without-labels[Pull requests must not have these labels (default: `do not merge`, `new formula`, `automerge-skip`, `CI-published-bottle-commits`)]' \ '--workflow[Workflow file to use with `brew pr-publish`]' } # brew pr-publish _brew_pr_publish() { _arguments \ - '--branch[Branch to publish to (default: `master`)]' \ + '--autosquash[If supported on the target tap, automatically reformat and reword commits to our preferred format]' \ + '--branch[Branch to use the workflow from (default: `master`)]' \ + '--commit-bottles-to-pr-branch[Push bottle commits to the pull request branch]' \ '--debug[Display any debugging information]' \ '--help[Show this message]' \ - '(--no-autosquash)--message[Message to include when autosquashing revision bumps, deletions, and rebuilds]' \ - '(--message)--no-autosquash[Skip automatically reformatting and rewording commits in the pull request to the preferred format, even if supported on the target tap]' \ + '--large-runner[Run the upload job on a large runner]' \ + '--message[Message to include when autosquashing revision bumps, deletions, and rebuilds]' \ + '--no-autosquash[Skip automatically reformatting and rewording commits in the pull request to the preferred format, even if supported on the target tap]' \ '--quiet[Make some output more quiet]' \ '--tap[Target tap repository (default: `homebrew/core`)]' \ '--verbose[Make some output more verbose]' \ @@ -1435,16 +1439,17 @@ _brew_pr_publish() { _brew_pr_pull() { _arguments \ '--artifact[Download artifacts with the specified name (default: `bottles`)]' \ + '(--clean)--autosquash[Automatically reformat and reword commits in the pull request to our preferred format]' \ '--branch-okay[Do not warn if pulling to a branch besides the repository default (useful for testing)]' \ - '--clean[Do not amend the commits from pull requests]' \ + '(--autosquash)--clean[Do not amend the commits from pull requests]' \ '--committer[Specify a committer name and email in `git`'\''s standard author format]' \ '--debug[Display any debugging information]' \ '--dry-run[Print what would be done rather than doing it]' \ '--help[Show this message]' \ '--ignore-missing-artifacts[Comma-separated list of workflows which can be ignored if they have not been run]' \ '--keep-old[If the formula specifies a rebuild version, attempt to preserve its value in the generated DSL]' \ - '(--no-autosquash)--message[Message to include when autosquashing revision bumps, deletions, and rebuilds]' \ - '(--message)--no-autosquash[Skip automatically reformatting and rewording commits in the pull request to our preferred format]' \ + '--message[Message to include when autosquashing revision bumps, deletions, and rebuilds]' \ + '--no-autosquash[Skip automatically reformatting and rewording commits in the pull request to our preferred format]' \ '--no-cherry-pick[Do not cherry-pick commits from the pull request branch]' \ '--no-commit[Do not generate a new commit before uploading]' \ '--no-upload[Download the bottles but don'\''t upload them]' \ diff --git a/docs/Manpage.md b/docs/Manpage.md index 36eb479dddf93..fb8ac72a8e38f 100644 --- a/docs/Manpage.md +++ b/docs/Manpage.md @@ -1330,11 +1330,13 @@ Find pull requests that can be automatically merged using `brew pr-publish`. * `--with-label`: Pull requests must have this label. * `--without-labels`: - Pull requests must not have these labels (default: `do not merge`, `new formula`, `automerge-skip`). + Pull requests must not have these labels (default: `do not merge`, `new formula`, `automerge-skip`, `CI-published-bottle-commits`). * `--without-approval`: Pull requests do not require approval to be merged. * `--publish`: Run `brew pr-publish` on matching pull requests. +* `--autosquash`: + Instruct `brew pr-publish` to automatically reformat and reword commits in the pull request to the preferred format. * `--no-autosquash`: Instruct `brew pr-publish` to skip automatically reformatting and rewording commits in the pull request to the preferred format. * `--ignore-failures`: @@ -1345,10 +1347,16 @@ Find pull requests that can be automatically merged using `brew pr-publish`. Publish bottles for a pull request with GitHub Actions. Requires write access to the repository. +* `--commit-bottles-to-pr-branch`: + Push bottle commits to the pull request branch. +* `--autosquash`: + If supported on the target tap, automatically reformat and reword commits to our preferred format. * `--no-autosquash`: Skip automatically reformatting and rewording commits in the pull request to the preferred format, even if supported on the target tap. +* `--large-runner`: + Run the upload job on a large runner. * `--branch`: - Branch to publish to (default: `master`). + Branch to use the workflow from (default: `master`). * `--message`: Message to include when autosquashing revision bumps, deletions, and rebuilds. * `--tap`: @@ -1374,6 +1382,8 @@ Requires write access to the repository. Do not amend the commits from pull requests. * `--keep-old`: If the formula specifies a rebuild version, attempt to preserve its value in the generated DSL. +* `--autosquash`: + Automatically reformat and reword commits in the pull request to our preferred format. * `--no-autosquash`: Skip automatically reformatting and rewording commits in the pull request to our preferred format. * `--branch-okay`: diff --git a/manpages/brew.1 b/manpages/brew.1 index 8d3e4f84a1f04..9fc16a36f8299 100644 --- a/manpages/brew.1 +++ b/manpages/brew.1 @@ -1898,7 +1898,7 @@ Pull requests must have this label\. . .TP \fB\-\-without\-labels\fR -Pull requests must not have these labels (default: \fBdo not merge\fR, \fBnew formula\fR, \fBautomerge\-skip\fR)\. +Pull requests must not have these labels (default: \fBdo not merge\fR, \fBnew formula\fR, \fBautomerge\-skip\fR, \fBCI\-published\-bottle\-commits\fR)\. . .TP \fB\-\-without\-approval\fR @@ -1909,6 +1909,10 @@ Pull requests do not require approval to be merged\. Run \fBbrew pr\-publish\fR on matching pull requests\. . .TP +\fB\-\-autosquash\fR +Instruct \fBbrew pr\-publish\fR to automatically reformat and reword commits in the pull request to the preferred format\. +. +.TP \fB\-\-no\-autosquash\fR Instruct \fBbrew pr\-publish\fR to skip automatically reformatting and rewording commits in the pull request to the preferred format\. . @@ -1920,12 +1924,24 @@ Include pull requests that have failing status checks\. Publish bottles for a pull request with GitHub Actions\. Requires write access to the repository\. . .TP +\fB\-\-commit\-bottles\-to\-pr\-branch\fR +Push bottle commits to the pull request branch\. +. +.TP +\fB\-\-autosquash\fR +If supported on the target tap, automatically reformat and reword commits to our preferred format\. +. +.TP \fB\-\-no\-autosquash\fR Skip automatically reformatting and rewording commits in the pull request to the preferred format, even if supported on the target tap\. . .TP +\fB\-\-large\-runner\fR +Run the upload job on a large runner\. +. +.TP \fB\-\-branch\fR -Branch to publish to (default: \fBmaster\fR)\. +Branch to use the workflow from (default: \fBmaster\fR)\. . .TP \fB\-\-message\fR @@ -1967,6 +1983,10 @@ Do not amend the commits from pull requests\. If the formula specifies a rebuild version, attempt to preserve its value in the generated DSL\. . .TP +\fB\-\-autosquash\fR +Automatically reformat and reword commits in the pull request to our preferred format\. +. +.TP \fB\-\-no\-autosquash\fR Skip automatically reformatting and rewording commits in the pull request to our preferred format\. .