From 6dcddd17b3af3c37929aadd02be3422674623533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 28 Sep 2026 14:32:39 +0200 Subject: [PATCH] Allow pushing commits with the SSH protocol --- README.md | 10 ++++++---- src/bin/rustc_josh_sync.rs | 20 ++++++++++++++++++-- src/josh.rs | 15 +++++++++++++-- src/sync.rs | 19 +++++++++++++++++-- 4 files changed, 54 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index fa4185b..9c3a644 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ jobs: with: github-app-id: ${{ vars.APP_CLIENT_ID }} # Must end with [bot] - pr-author: "github-actions[bot]" + pr-author: "github-actions[bot]" # If you want the Zulip post functionality #zulip-stream-id: 1234 # optional #zulip-bot-email: subtree-gha-notif-bot@rust-lang.zulipchat.com # optional @@ -88,9 +88,11 @@ You will need to have a GitHub app configured on the repository with permissions ## Git peculiarities -NOTE: If you use Git/SSH protocol to push to your fork of [rust-lang/rust], -ensure that you have this entry in your Git config, -else the 2 steps that follow would prompt for a username and password: +### SSH protocol + +If you use the Git/SSH protocol to push to your fork of [rust-lang/rust], you can pass the `--protocol=ssh` flag to `rustc-josh-sync push`. + +As an alternative, you could override all HTTPS connections with a SSH connection using this entry in your Git config: ``` [url "git@github.com:"] diff --git a/src/bin/rustc_josh_sync.rs b/src/bin/rustc_josh_sync.rs index e69e0d5..de08138 100644 --- a/src/bin/rustc_josh_sync.rs +++ b/src/bin/rustc_josh_sync.rs @@ -4,7 +4,7 @@ use rustc_josh_sync::SyncContext; use rustc_josh_sync::config::{JoshConfig, load_config}; use rustc_josh_sync::josh::{JoshProxy, try_install_josh_proxy}; use rustc_josh_sync::sync::{ - DEFAULT_UPSTREAM_REPO, FilterVersion, GitSync, PullMode, RustcPullError, + DEFAULT_UPSTREAM_REPO, FilterVersion, GitProtocol, GitSync, PullMode, RustcPullError, }; use rustc_josh_sync::utils::{get_current_head_sha, nightly_date_to_sha, prompt}; use std::path::{Path, PathBuf}; @@ -57,11 +57,22 @@ enum Command { /// Your GitHub usename where the fork is located username: String, + + /// Which protocol to use to push the resulting commit to your fork's branch. + #[clap(long, default_value = "https")] + protocol: GitProtocolCli, + #[clap(flatten)] shared: SharedArgs, }, } +#[derive(clap::ValueEnum, Clone)] +enum GitProtocolCli { + Https, + Ssh, +} + #[derive(clap::Parser)] struct SharedArgs { /// Path to the josh-sync TOML config file. @@ -158,12 +169,17 @@ fn main() -> anyhow::Result<()> { username, branch, shared, + protocol, } => { let ctx = load_context(shared.config_path, shared.rust_version_path)?; let josh = get_josh_proxy(shared.josh_proxy, shared.verbose)?; let sync = GitSync::new(ctx.clone(), josh, shared.verbose); + let protocol = match protocol { + GitProtocolCli::Https => GitProtocol::Https, + GitProtocolCli::Ssh => GitProtocol::Ssh, + }; if let Err(error) = sync - .rustc_push(&username, &branch) + .rustc_push(&username, &branch, protocol) .context("cannot perform push") { if !shared.verbose { diff --git a/src/josh.rs b/src/josh.rs index 0028cb1..1e4c227 100644 --- a/src/josh.rs +++ b/src/josh.rs @@ -1,4 +1,5 @@ use crate::config::JoshConfig; +use crate::sync::GitProtocol; use crate::utils::{is_inside_ci, is_null_sha, run_command_by_path}; use anyhow::Context; use std::net::{SocketAddr, TcpStream}; @@ -165,11 +166,21 @@ pub struct RunningJoshProxy { } impl RunningJoshProxy { - pub fn git_url(&self, repo: &str, commit: Option<&str>, filter: &str) -> String { + pub fn git_url( + &self, + repo: &str, + commit: Option<&str>, + filter: &str, + protocol: &GitProtocol, + ) -> String { let commit = commit.map(|c| format!("@{c}")).unwrap_or_default(); let filter = urlencoding::encode(filter); + let protocol = match protocol { + GitProtocol::Https => "http", + GitProtocol::Ssh => "ssh", + }; format!( - "http://localhost:{}/{repo}.git{commit}{filter}.git", + "{protocol}://localhost:{}/{repo}.git{commit}{filter}.git", self.port ) } diff --git a/src/sync.rs b/src/sync.rs index dbdb738..1836b50 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -73,6 +73,11 @@ impl BumpedVersion { } } +pub enum GitProtocol { + Https, + Ssh, +} + pub struct GitSync { context: SyncContext, proxy: JoshProxy, @@ -163,6 +168,7 @@ impl GitSync { &upstream_repo, Some(&upstream_sha), &construct_josh_filter(&self.context.config), + &GitProtocol::Https, ); // Fetch given rustc commit. @@ -287,7 +293,12 @@ After you fix the conflicts, `git add` the changes and run `git merge --continue }) } - pub fn rustc_push(&self, username: &str, branch: &str) -> anyhow::Result<()> { + pub fn rustc_push( + &self, + username: &str, + branch: &str, + protocol: GitProtocol, + ) -> anyhow::Result<()> { ensure_clean_git_state(self.verbose)?; let base_upstream_sha = self.context.last_upstream_sha.clone().unwrap_or_default(); @@ -301,8 +312,12 @@ After you fix the conflicts, `git add` the changes and run `git merge --continue &format!("{username}/rust"), None, &construct_josh_filter(&self.context.config), + &protocol, ); - let user_upstream_url = format!("https://github.com/{username}/rust"); + let user_upstream_url = match protocol { + GitProtocol::Https => format!("https://github.com/{username}/rust"), + GitProtocol::Ssh => format!("ssh://git@github.com/{username}/rust.git"), + }; let rustc_git = prepare_rustc_checkout(self.verbose).context("cannot prepare rustc checkout")?;