feat(#1778): add hive-forge ci-rerun to re-run CI without an empty commit
When a CI run fails for a transient reason (remote-builder flap, cold-daemon window, act_runner hiccup) the only retrigger path was an empty commit, which litters PR history and forces a force-push to clean up. This verb POSTs the rerun action directly. - `ci-rerun --run <n>` re-runs all jobs of a run (run number = the `runs/<n>` the UI shows, same value ci-log / artifact-get take, surfaced as a CI context's target_url by pr-status). - `--pr <n>` resolves the run from the PR head sha's CI status target_url. - `--job <i>` re-runs a single job. Forgejo exposes no REST endpoint for rerunning a run, so this rides the run page's web routes (`<base>/<owner>/<repo>/actions/runs/<n>[/jobs/<i>]/rerun`) via a new `Client::post_web_no_content` (web base like post_json_web, tolerates the redirect/empty response the rerun handler returns). Mirrors ci-log's web-route approach + auth path. docs/tools/forge.md updated with the verb.
This commit is contained in:
parent
658812c263
commit
cd4bdf4eea
5 changed files with 167 additions and 0 deletions
|
|
@ -321,6 +321,26 @@ impl Client {
|
|||
decode_json(resp, &format!("POST {url}"))
|
||||
}
|
||||
|
||||
/// POST to a base-relative *web* path (NOT under `/api/v1/`) whose
|
||||
/// response carries no useful body — e.g. the Actions run rerun
|
||||
/// endpoints (`<base>/<owner>/<repo>/actions/runs/<run>/rerun`), which
|
||||
/// answer with a redirect to the run page rather than JSON. Same
|
||||
/// token-auth path as `post_json_web` (the web router accepts a
|
||||
/// token-authed doer and skips CSRF for non-session auth); the bodyless
|
||||
/// POST mirrors the form-handler's expectations (run/job come from the
|
||||
/// URL). reqwest follows the redirect, so a 2xx on the final hop is
|
||||
/// success. `path` should start with `/`.
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns an error on a transport failure or a non-2xx final status
|
||||
/// (e.g. `404` for an unknown run).
|
||||
pub fn post_web_no_content(&self, path: &str) -> Result<()> {
|
||||
let url = self.web_url(path);
|
||||
let resp = self.http.post(&url).send().context("POST")?;
|
||||
check_status(resp, &format!("POST {url}"))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// GET a raw (non-API) URL and return the response body as bytes.
|
||||
/// The client's auth headers are still sent — Forgejo requires them
|
||||
/// for private attachment downloads. Uses the full URL as-is; the
|
||||
|
|
|
|||
Loading…
Reference in a new issue