chore(devex): add safe Gitea git wrapper
This commit is contained in:
parent
3ddc0c50a6
commit
4b01f4f754
|
|
@ -97,4 +97,72 @@ Use one of these existing rollback methods:
|
|||
previously known good immutable digest.
|
||||
|
||||
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
166
scripts/git-update.sh
Executable 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 "$@"
|
||||
Loading…
Reference in New Issue
Block a user