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:
@@ -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
@@ -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
@@ -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
|
||||
Reference in New Issue
Block a user