defmodule GitGud.Secrets.ReservedNames do
@moduledoc """
Rejects secret/variable names the CI runtime injects itself.
A user secret named `GITHUB_TOKEN` (say) silently overrides the
forge's per-job token in the runner's `secrets`/env, which then breaks
`actions/checkout` on private repos ("could not read Username"). Mirror
GitHub's rule (no `GITHUB_` prefix) and extend it to the Forgejo/act
runtime prefixes so these can't be shadowed.
"""
import Ecto.Changeset
# Case-insensitive prefixes owned by the runtime (token, context,
# runner/actions env). CI_* is intentionally NOT reserved — built-in
# vars like CI_REGISTRY are meant to be user-overridable.
@reserved_prefixes ~w(GITHUB_ GITEA_ FORGEJO_ RUNNER_ ACTIONS_)
@doc """
Add a validation error if the changeset's `field` (default `:name`)
starts with a runtime-reserved prefix.
"""
def validate_not_reserved(changeset, field \\ :name) do
validate_change(changeset, field, fn ^field, value ->
up = String.upcase(value || "")
if Enum.any?(@reserved_prefixes, &String.starts_with?(up, &1)) do
[{field, "is reserved by the CI runtime (GITHUB_*, GITEA_*, FORGEJO_*, RUNNER_*, ACTIONS_*)"}]
else
[]
end
end)
end
end
1.2 KiB · text
5af55d9