chore(devex): add safe Gitea git wrapper

This commit is contained in:
Chris Christiansen 2026-09-19 00:54:59 +00:00
parent 3ddc0c50a6
commit 4b01f4f754
2 changed files with 235 additions and 1 deletions

View File

@ -98,3 +98,71 @@ Use one of these existing rollback methods:
Use `./scripts/check-live-services.sh` to record the currently active revisions Use `./scripts/check-live-services.sh` to record the currently active revisions
and images before a release. and images before a release.
---
## Appendix: `git-update.sh` Script
### Hensikt og sikkerhetsmodell
`scripts/git-update.sh` er en sikker wrapper for git-operasjoner mot prosjektets Gitea-repository, designet for å forhindre vanlige feil og håndheve beste praksis for versjonskontroll.
### Kommandoer
Scriptet bruker et subkommando-grensesnitt:
#### **`./scripts/git-update.sh status`**
Viser status for repositoryet. Dette er standardvalget hvis ingen subkommando gis.
#### **`./scripts/git-update.sh commit [--allow-main] -m "<melding>" -- <fil1> [...]`**
Stager en eksplisitt liste filer, validerer, og kjører deretter en interaktiv `commit` og `push` i én operasjon.
- **`--allow-main`**: Valgfritt flagg som må brukes for å commite direkte til `main`-branchen.
- **`-m "<melding>"`**: En obligatorisk commit-melding.
- **`-- <filer>`**: En eller flere filer som skal behandles.
#### **`./scripts/git-update.sh push [--allow-main]`**
Pusher en *allerede opprettet* lokal commit som ennå ikke er lastet opp til Gitea.
### Sikkerhetsgarantier
1. **Gitea-validering**: Scriptet verifiserer at `origin` peker til prosjektets godkjente Gitea-repository. Det vil nekte å kjøre hvis `origin` er GitHub eller en ukjent URL.
2. **Ingen Pre-staged Commits**: Scriptet avbryter hvis det finnes filer i "staging area" *før* `git add`-kommandoen kjøres. Dette forhindrer at utilsiktede endringer blir med i en commit.
3. **Eksplisitt filliste**: Kun filene som listes eksplisitt etter `--` blir lagt til i staging. Scriptet bruker aldri `git add .` eller `git add -A`.
4. **Whitespace-sjekker**: Før og etter staging kjøres `git diff --check` for å avdekke og stoppe ved whitespace-feil.
5. **Interaktiv bekreftelse**: Før en commit og push, vises en status over stagede filer, og brukeren må bekrefte med `y`. Hvis brukeren avbryter, forblir de eksplisitt stagede filene i staging area, men ingen commit eller push utføres.
6. **Beskyttelse av `main`**: Operasjoner (commit/push) mot `main`-branchen er blokkert med mindre det eksplisitte `--allow-main` flagget er brukt.
7. **Trygg Push**: Bruker `git push origin <current_branch>`. Bruker aldri `git push --force`.
### Eksempler
**Sjekk status:**
```bash
./scripts/git-update.sh status
```
**Commit og push til en feature-branch:**
```bash
./scripts/git-update.sh commit -m "feat: Add new script" -- \
scripts/new-script.sh \
docs/new-doc.md
```
**Push en allerede opprettet commit:**
```bash
./scripts/git-update.sh push
```
**Avbrudd på grunn av pre-stagede endringer:**
```text
FEIL: Repositoryet har allerede staged endringer.
Avbryter for å hindre at filer utenfor den eksplisitte fillisten blir committet.
Kjør: git diff --cached --name-status
```

166
scripts/git-update.sh Executable file
View File

@ -0,0 +1,166 @@
#!/usr/bin/env bash
set -euo pipefail
# En sikker wrapper for å adde, committe og pushe filer til Gitea.
readonly REPO_ROOT="$(git rev-parse --show-toplevel)"
readonly ALLOWED_ORIGIN_CONTAINS="git.vauco.no/chris/OSVauco.git"
error() {
echo "FEIL: $1" >&2
exit 1
}
check_repository() {
local origin_url
origin_url="$(git remote get-url origin 2>/dev/null)" ||
error "Fant ikke Git remote 'origin'."
if [[ "${origin_url}" == *github.com* ]]; then
error "Remote 'origin' peker på GitHub. OSVauco bruker kun Gitea."
fi
if [[ "${origin_url}" != *"${ALLOWED_ORIGIN_CONTAINS}"* ]]; then
error "Remote 'origin' er ikke godkjent Gitea-remote: ${origin_url}"
fi
}
check_main_branch() {
local current_branch
current_branch="$(git rev-parse --abbrev-ref HEAD)"
if [[ "${current_branch}" == "main" ]]; then
error "Direkte operasjoner på 'main' krever '--allow-main' flagget."
fi
}
handle_status() {
git status
}
handle_commit() {
local allow_main=false
if [[ "${1:-}" == "--allow-main" ]]; then
allow_main=true
shift
fi
if ! $allow_main; then
check_main_branch
fi
if [[ $# -lt 4 || "$1" != "-m" || "$3" != "--" ]]; then
error "Bruk: commit [--allow-main] -m \"<melding>\" -- <fil> [<fil>...]"
fi
local msg="$2"
shift 3
local files=("$@")
if [[ -z "${msg//[[:space:]]/}" ]]; then
error "Commit-meldingen kan ikke være tom."
fi
if ! git diff --cached --quiet --exit-code; then
echo "FEIL: Repositoryet har allerede staged endringer." >&2
echo "Avbryter for å hindre at filer utenfor den eksplisitte fillisten blir committet." >&2
echo "Kjør: git diff --cached --name-status" >&2
exit 1
fi
for file in "${files[@]}"; do
if [[ ! -e "${file}" ]] && ! git ls-files --error-unmatch -- "${file}" >/dev/null 2>&1; then
error "Filen finnes ikke og er ikke en Git-tracked fil: ${file}"
fi
local real_path
real_path="$(realpath -m -- "${file}")"
if [[ "${real_path}" != "${REPO_ROOT}" && "${real_path}" != "${REPO_ROOT}/"* ]]; then
error "Filen '${file}' er utenfor repository-roten."
fi
done
echo "Kjører whitespace-sjekk før staging..."
git diff --check -- "${files[@]}" || error "Whitespace-feil funnet. Avbryter."
git add -- "${files[@]}"
if git diff --cached --quiet --exit-code; then
echo "Ingen endringer ble staged fra de oppgitte filene. Ingenting å committe."
exit 0
fi
echo "Kjører whitespace-sjekk etter staging..."
git diff --cached --check || error "Whitespace-feil funnet i staging. Avbryter."
echo
echo "Følgende endringer vil bli committet:"
echo "------------------------------------"
git --no-pager diff --cached --name-status
echo "------------------------------------"
git --no-pager diff --cached --stat
echo "------------------------------------"
echo
read -r -p "Commit og push de viste filene til Gitea? [y/N] " reply
if [[ ! "${reply}" =~ ^[Yy]$ ]]; then
echo "Avbrutt. Endringene er staged, men ikke committet."
exit 0
fi
git commit -m "${msg}"
echo "✅ Commit opprettet."
echo "Pusher commit til Gitea..."
local current_branch
current_branch="$(git rev-parse --abbrev-ref HEAD)"
git push origin "${current_branch}"
echo "✅ Commit og push fullført."
}
handle_push() {
local allow_main=false
if [[ "${1:-}" == "--allow-main" ]]; then
allow_main=true
shift
fi
if [[ "$#" -ne 0 ]]; then
error "Bruk: push [--allow-main]"
fi
if ! $allow_main; then
check_main_branch
fi
local current_branch
current_branch="$(git rev-parse --abbrev-ref HEAD)"
echo "Pusher til origin/${current_branch}..."
git push origin "${current_branch}"
echo "✅ Push fullført."
}
main() {
cd "${REPO_ROOT}"
check_repository
local cmd=${1:-status}
shift || true
case "${cmd}" in
status)
handle_status "$@"
;;
commit)
handle_commit "$@"
;;
push)
handle_push "$@"
;;
*)
error "Ukjent kommando: '${cmd}'. Gyldige kommandoer er 'status', 'commit', 'push'."
;;
esac
}
main "$@"