test/openagents/push_remote_contract_test.exs

main at 58e6347eeb72 · 5 KB

defmodule OpenAgents.PushRemoteContractTest do
  use ExUnit.Case, async: true

  @script "ops/ci/push-remote-check.sh"
  @installer "ops/dev/install-push-guard.sh"

  defp check(arguments, environment \\ []) do
    System.cmd("sh", [@script | arguments], env: environment, stderr_to_stdout: true)
  end

  test "a GitHub remote is refused, whatever its URL form" do
    for url <- [
          "git@github.com:OpenAgentsInc/openagents.com.git",
          "https://github.com/OpenAgentsInc/openagents.com.git",
          "ssh://git@github.com/OpenAgentsInc/openagents.com.git"
        ] do
      assert {output, 1} = check(["origin", url])
      assert output =~ "Refusing to push"
      assert output =~ "git push openagents HEAD:main"
    end
  end

  test "the forge is admitted over HTTPS and SSH" do
    for url <- [
          "https://openagents.com/OpenAgentsInc/openagents.com.git",
          "https://staging.openagents.com/OpenAgentsInc/openagents.com.git",
          "git@openagents.com:OpenAgentsInc/openagents.com.git"
        ] do
      assert {_output, 0} = check(["openagents", url])
    end
  end

  # A host that merely ends in the forge's name is a different host.
  test "a lookalike host is refused" do
    assert {_output, 1} = check(["origin", "https://openagents.com.example.net/x.git"])
  end

  test "the override admits one push and says so" do
    assert {output, 0} =
             check(
               ["origin", "git@github.com:OpenAgentsInc/openagents.com.git"],
               [{"OPENAGENTS_ALLOW_NON_FORGE_PUSH", "1"}]
             )

    assert output =~ "push_remote_override"
  end

  test "the installer leaves a clone refusing GitHub" do
    root = Path.join(System.tmp_dir!(), "push-guard-#{System.unique_integer([:positive])}")
    on_exit(fn -> File.rm_rf!(root) end)

    File.mkdir_p!(Path.join(root, "ops/ci"))
    File.mkdir_p!(Path.join(root, "ops/dev"))
    File.cp!(@script, Path.join(root, @script))
    File.cp!(@installer, Path.join(root, @installer))
    {_output, 0} = System.cmd("git", ["init", "-q", root])

    assert {_output, 0} = System.cmd("sh", [@installer], cd: root, stderr_to_stdout: true)

    hook = Path.join(root, ".git/hooks/pre-push")
    assert File.exists?(hook)

    # The guard travels with the hook, so a worktree on a branch that predates
    # it still refuses the wrong remote instead of failing to find a file.
    assert File.exists?(Path.join(root, ".git/hooks/openagents-push-remote-check.sh"))
    File.rm!(Path.join(root, @script))

    assert {output, 1} =
             System.cmd("sh", [hook, "origin", "git@github.com:OpenAgentsInc/x.git"],
               cd: root,
               stderr_to_stdout: true
             )

    assert output =~ "Refusing to push"

    # The guard alone: a clone that installs it must not inherit the release
    # gate, which needs a disposable database and minutes of wall clock.
    refute File.read!(hook) =~ "gate.sh"
  end

  test "the installer refuses to overwrite a hook it does not recognize" do
    root = Path.join(System.tmp_dir!(), "push-guard-#{System.unique_integer([:positive])}")
    on_exit(fn -> File.rm_rf!(root) end)

    File.mkdir_p!(Path.join(root, "ops/ci"))
    File.mkdir_p!(Path.join(root, "ops/dev"))
    File.cp!(@script, Path.join(root, @script))
    File.cp!(@installer, Path.join(root, @installer))
    {_output, 0} = System.cmd("git", ["init", "-q", root])

    hook = Path.join(root, ".git/hooks/pre-push")
    File.write!(hook, "#!/bin/sh\nexit 0\n")

    assert {output, 1} = System.cmd("sh", [@installer], cd: root, stderr_to_stdout: true)
    assert output =~ "--force"
    assert File.read!(hook) == "#!/bin/sh\nexit 0\n"

    assert {_output, 0} =
             System.cmd("sh", [@installer, "--force"], cd: root, stderr_to_stdout: true)

    assert File.read!(hook) =~ "openagents-push-guard"
  end

  test "--ensure installs quietly and never fails the build" do
    root = Path.join(System.tmp_dir!(), "push-guard-#{System.unique_integer([:positive])}")
    on_exit(fn -> File.rm_rf!(root) end)

    File.mkdir_p!(Path.join(root, "ops/ci"))
    File.mkdir_p!(Path.join(root, "ops/dev"))
    File.cp!(@script, Path.join(root, @script))
    File.cp!(@installer, Path.join(root, @installer))
    {_output, 0} = System.cmd("git", ["init", "-q", root])

    assert {"", 0} = System.cmd("sh", [@installer, "--ensure"], cd: root, stderr_to_stdout: true)
    assert File.read!(Path.join(root, ".git/hooks/pre-push")) =~ "openagents-push-guard"

    # A hook someone else installed is a decision, not an obstacle: say so and
    # let precommit continue.
    File.write!(Path.join(root, ".git/hooks/pre-push"), "#!/bin/sh\nexit 0\n")

    assert {output, 0} =
             System.cmd("sh", [@installer, "--ensure"], cd: root, stderr_to_stdout: true)

    assert output =~ "not the push guard"
    assert File.read!(Path.join(root, ".git/hooks/pre-push")) == "#!/bin/sh\nexit 0\n"
  end

  test "the pre-push hook runs the check before the release gate" do
    hook = File.read!(".githooks/pre-push")

    assert hook =~ "ops/ci/push-remote-check.sh"
    assert hook =~ "ops/ci/gate.sh"

    [check_at, gate_at] =
      for marker <- ["push-remote-check.sh", "gate.sh"] do
        hook |> String.split(marker) |> hd() |> String.length()
      end

    assert check_at < gate_at
  end
end