config PRs: remove the hive's config-PR webhook, poll and core merge
An operator's merge on the forge deploys a config PR through
swarm-controller's DeployRequest{rev}. The hive-side path that queued a
MergeConfigPr approval and merged the PR as `core` goes:
- the `/webhook/config-pr` receiver, its HMAC secret, the WebhookRegister
boot node and the org-hook registration; the hive vhost's `/webhook/`
location
- the 5-minute config-PR poll
- ApprovalKind::MergeConfigPr, its dashboard card, and the deploy DAG it
drove (DeployWindow, MergeVerify, DeployApply, FinalizeDeploy,
DeployTail), with verify_commit, the two-phase meta deploy, rollback
refs, the PR-failure comment and forge/pr_merge.rs
- `fetched_sha`, `sha_short`/`pr_number` on approval events, and
`sha`/`tag` on HelperEvent::ApprovalResolved: only the merge path set
them
`config_repo`, `merged_pr_for_commit` and `post_pr_comment` move to
forge/pr_comment.rs for the merged-rev deploy's refusal comment.
Approvals v5 drops stored `merge_config_pr` rows; a test reopens a v4
database holding them.
Closes #4850
This commit is contained in:
parent
a5ea015bc6
commit
efbfec6d01
39 changed files with 286 additions and 3199 deletions
|
|
@ -135,55 +135,6 @@ pub async fn git_tag(dir: &Path, name: &str, target: &str) -> Result<()> {
|
|||
git(dir, &["tag", name, target]).await
|
||||
}
|
||||
|
||||
/// Plant an annotated tag with `body` as the message. Used for
|
||||
/// `failed/<id>` (body = build error) and `denied/<id>` (body =
|
||||
/// operator note). Multi-line bodies handled via stdin so we don't
|
||||
/// have to escape anything.
|
||||
pub async fn git_tag_annotated(dir: &Path, name: &str, target: &str, body: &str) -> Result<()> {
|
||||
use tokio::io::AsyncWriteExt;
|
||||
// Annotated tags are git objects, so they need a tagger identity
|
||||
// (same constraint as a commit). Pass the hive-c0re identity
|
||||
// inline rather than relying on a global git config — applied
|
||||
// repos are hive-c0re-owned and the host's user might not have
|
||||
// user.email set.
|
||||
let mut child = git_command()
|
||||
.current_dir(dir)
|
||||
.args([
|
||||
"-c",
|
||||
&format!("user.name={GIT_NAME}"),
|
||||
"-c",
|
||||
&format!("user.email={GIT_EMAIL}"),
|
||||
"tag",
|
||||
"-a",
|
||||
name,
|
||||
target,
|
||||
"-F",
|
||||
"-",
|
||||
])
|
||||
.stdin(std::process::Stdio::piped())
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.with_context(|| format!("spawn git tag -a {name} in {}", dir.display()))?;
|
||||
if let Some(mut stdin) = child.stdin.take() {
|
||||
stdin
|
||||
.write_all(body.as_bytes())
|
||||
.await
|
||||
.context("write tag body to git stdin")?;
|
||||
// Drop closes stdin so git can finish reading.
|
||||
drop(stdin);
|
||||
}
|
||||
let out = child.wait_with_output().await.context("wait git tag -a")?;
|
||||
if !out.status.success() {
|
||||
bail!(
|
||||
"git tag -a {name} failed ({}): {}",
|
||||
out.status,
|
||||
String::from_utf8_lossy(&out.stderr).trim()
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Replace working tree + index with the tree at `target` without
|
||||
/// moving HEAD. `applied/main` stays pointing at the last known-good
|
||||
/// `deployed/*` while we let `nixos-container update` evaluate the
|
||||
|
|
@ -252,13 +203,3 @@ pub async fn git_is_ancestor(dir: &Path, ancestor: &str, descendant: &str) -> Re
|
|||
),
|
||||
}
|
||||
}
|
||||
|
||||
/// Delete a ref. The counterpart to [`git_update_ref`] for the bookkeeping
|
||||
/// refs a deploy parks in the applied repo (`refs/hyperhive/rollback/<id>`,
|
||||
/// which records the pre-merge `main` so the deploy tail can compensate a
|
||||
/// merge that landed but never finalized). `update-ref -d` is a no-op-free
|
||||
/// delete: it errors if the ref does not exist, so callers that treat absence
|
||||
/// as "nothing to undo" should check with [`git_rev_parse`] first.
|
||||
pub async fn git_delete_ref(dir: &Path, refname: &str) -> Result<()> {
|
||||
git(dir, &["update-ref", "-d", refname]).await
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,8 @@ mod setup;
|
|||
mod tests;
|
||||
|
||||
pub use git::{
|
||||
git, git_authed, git_command, git_command_authed, git_delete_ref, git_is_ancestor,
|
||||
git_read_tree_reset, git_rev_parse, git_tag, git_tag_annotated, git_update_ref,
|
||||
git_update_ref_cas,
|
||||
git, git_authed, git_command, git_command_authed, git_is_ancestor, git_read_tree_reset,
|
||||
git_rev_parse, git_tag, git_update_ref, git_update_ref_cas,
|
||||
};
|
||||
pub use host_config::write_dropins;
|
||||
pub use setup::{
|
||||
|
|
|
|||
|
|
@ -98,8 +98,8 @@ async fn ensure_applied_remote(proposed_dir: &Path, name: &str) -> Result<()> {
|
|||
/// Set up the applied repo. First-spawn only: init the repo, pull
|
||||
/// proposed's initial commit in via `git fetch`, tag it `deployed/0`.
|
||||
/// This is the *only* time hive-c0re reads from `proposed` for an
|
||||
/// agent — subsequent config changes are fetched from the reviewed
|
||||
/// forge PR head at merge time (see `actions::run_deploy_apply`).
|
||||
/// agent — subsequent config changes are fetched from the forge's `main`
|
||||
/// (see `actions::advance_applied_to_rev`).
|
||||
///
|
||||
/// `proposed_dir` is `None` on rebuild paths where the repo already
|
||||
/// exists — we just verify it's the right shape and bail otherwise.
|
||||
|
|
|
|||
Loading…
Reference in a new issue