feat: workspace-bootstrap — init SSH/git/Cursor для Mac и Windows

Единый workspace.local.env для адресов и паролей, init-machine,
Set-GitRemotes, push-safe и check-no-secrets для политики kalinamall/github.
This commit is contained in:
Andrey Lutsenko
2026-06-14 19:34:52 +10:00
parent 8e2a4ac1b9
commit 834595df6b
18 changed files with 813 additions and 8 deletions
@@ -0,0 +1,28 @@
#Requires -Version 5.1
param(
[Parameter(Mandatory = $true)]
[string]$Repo,
[string]$RepoDir = ''
)
$ErrorActionPreference = 'Stop'
$ScriptsDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$BootstrapRoot = Split-Path -Parent $ScriptsDir
$ShScript = Join-Path $ScriptsDir 'Set-GitRemotes.sh'
$gitBash = @(
"${env:ProgramFiles}\Git\bin\bash.exe",
"${env:ProgramFiles(x86)}\Git\bin\bash.exe"
) | Where-Object { Test-Path $_ } | Select-Object -First 1
$bashArgs = @($ShScript, $Repo)
if ($RepoDir) { $bashArgs = @($ShScript, '--repo-dir', $RepoDir, $Repo) }
if ($gitBash) {
& $gitBash @bashArgs
exit $LASTEXITCODE
}
Write-Host "Git Bash не найден."
exit 1
+85
View File
@@ -0,0 +1,85 @@
#!/usr/bin/env bash
# Настроить remotes для одного репозитория (только SSH)
set -Eeuo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=../lib/common.sh
source "$SCRIPT_DIR/../lib/common.sh"
usage() {
cat <<'EOF'
Usage: Set-GitRemotes.sh [--repo-dir PATH] REPO_NAME [HAS_GITHUB]
REPO_NAME каталог проекта (имя в repos.yaml)
HAS_GITHUB 1 или 0 (по умолчанию из repos.yaml)
Remotes: kalinamall, home, github (если включён). Без origin и без https.
EOF
}
REPO_NAME=""
REPO_DIR=""
HAS_GITHUB=""
while [[ $# -gt 0 ]]; do
case "$1" in
--repo-dir) REPO_DIR=$2; shift 2 ;;
-h | --help) usage; exit 0 ;;
*)
if [[ -z $REPO_NAME ]]; then REPO_NAME=$1
else HAS_GITHUB=$1
fi
shift
;;
esac
done
[[ -n $REPO_NAME ]] || { usage; exit 1; }
load_workspace_env
if [[ -z $REPO_DIR ]]; then
REPO_DIR="$(projects_dir)/$REPO_NAME"
fi
[[ -d $REPO_DIR/.git ]] || die "не git-репозиторий: $REPO_DIR"
if [[ -z $HAS_GITHUB ]]; then
HAS_GITHUB=$(each_repo | awk -v n="$REPO_NAME" '$1==n{print $2; exit}')
[[ -n $HAS_GITHUB ]] || die "репозиторий $REPO_NAME не найден в repos.yaml"
fi
cd "$REPO_DIR"
set_remote() {
local name=$1 url=$2
if git remote | grep -qx "$name"; then
git remote set-url "$name" "$url"
else
git remote add "$name" "$url"
fi
}
# Убрать origin/https если были
if git remote | grep -qx origin; then
local_url=$(git remote get-url origin 2>/dev/null || true)
if [[ $local_url == https://* ]]; then
log "удаляю origin с HTTPS: $local_url"
git remote remove origin
fi
fi
set_remote kalinamall "$(kalinamall_remote_url "$REPO_NAME")"
set_remote home "$(home_remote_url "$REPO_NAME")"
if [[ $HAS_GITHUB == 1 ]]; then
set_remote github "$(github_remote_url "$REPO_NAME")"
elif git remote | grep -qx github; then
log "удаляю github remote для $REPO_NAME (github: false)"
git remote remove github
fi
git branch -u kalinamall/main main 2>/dev/null || git branch -u kalinamall/main master 2>/dev/null || true
log "$REPO_NAME remotes:"
git remote -v
+75
View File
@@ -0,0 +1,75 @@
#!/usr/bin/env bash
# Блокирует push на github при подозрении на секреты в коммитах
set -Eeuo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# shellcheck source=lib/common.sh
source "$ROOT/lib/common.sh"
PATTERNS=(
'\.env$'
'SECRET_KEY'
'DATABASE_URL='
'password\s*=\s*["\x27][^"\x27]+'
'BEGIN (RSA |OPENSSH )?PRIVATE KEY'
'api[_-]?key'
'telegram.*token'
'smtp.*password'
'credentials\.json'
'google-services\.json'
'\.pem$'
'\.p12$'
'\.jks$'
)
scan_range() {
local range=$1
local hits=0
local files
files=$(git diff --name-only $range 2>/dev/null; git diff --cached --name-only 2>/dev/null)
files=$(echo "$files" | sort -u | grep -v '^$' || true)
while read -r f; do
[[ -z $f ]] && continue
[[ -f $f ]] || continue
case $f in
*.example | *.sample | *env.example | workspace.local.env.example) continue ;;
esac
for pat in "${PATTERNS[@]}"; do
if grep -qiE "$pat" "$f" 2>/dev/null; then
echo " SECRET? $f (pattern: $pat)"
hits=$((hits + 1))
fi
done
done <<<"$files"
return $hits
}
main() {
local remote="${1:-github}"
local branch
branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo main)
if ! git remote | grep -qx "$remote"; then
exit 0
fi
local range=""
if git rev-parse "$remote/$branch" >/dev/null 2>&1; then
range="$remote/$branch..HEAD"
else
range="HEAD"
fi
echo "[check-no-secrets] сканирование перед push $remote ($range)"
local n=0
scan_range "$range" || n=$?
if [[ $n -gt 0 ]]; then
echo "[check-no-secrets] найдено подозрительных совпадений: $n"
echo "push на $remote отменён. Проверьте diff или используйте только kalinamall."
exit 1
fi
echo "[check-no-secrets] OK"
}
main github