<# Atualiza C:\PilotDownloads\ com o conteúdo do repositório (branch main) https://gitea.magicis.com.br/PilotSupport/vlt-install e executa pilot_install.ps1 Recursos: - Instala/atualiza Git via winget - Evita abrir navegador (sem prompts do GCM) - Suporte a token do Gitea (param ou arquivo) - Copia por cima (não espelha) #> param( [string]$GitUser, # opcional: usuário do Gitea [string]$GitToken, # opcional: PAT do Gitea [string]$GitTokenPath # opcional: caminho de arquivo contendo somente o token ) $ErrorActionPreference = 'Stop' # ===== Configurações ===== $RepoUrl = 'https://gitea.magicis.com.br/PilotSupport/vlt-install' # sem credenciais na URL $Branch = 'main' $TargetDir = 'C:\PilotDownloads' $WorkDir = Join-Path $env:TEMP 'vlt-install_repo' $CopyLog = Join-Path $env:TEMP 'vlt-install_copy.log' # ===== Utilitárias ===== function Write-Info($m){ Write-Host "[INFO ] $m" -ForegroundColor Cyan } function Write-Ok($m) { Write-Host "[ OK ] $m" -ForegroundColor Green } function Write-Warn($m){ Write-Host "[WARN ] $m" -ForegroundColor Yellow } function Write-Err($m) { Write-Host "[ERRO ] $m" -ForegroundColor Red } function Ensure-Dir([string]$Path){ if (-not (Test-Path -LiteralPath $Path)) { New-Item -ItemType Directory -Path $Path -Force | Out-Null } } function Test-Winget { [bool](Get-Command winget -ErrorAction SilentlyContinue) } function Ensure-Git-WithWinget { if (-not (Test-Winget)) { Write-Err "winget não encontrado. Instale o 'App Installer' pela Microsoft Store para habilitar o winget." throw "winget ausente" } Write-Info "Verificando Git via winget..." $argsCommon = @('--accept-package-agreements','--accept-source-agreements','--silent') # Detecta se Git está instalado $gitInstalled = $false try { $list = winget list --id Git.Git -e @argsCommon 2>$null if ($list -match 'Git\s+Git') { $gitInstalled = $true } } catch { } if ($gitInstalled) { Write-Info "Atualizando Git (se necessário)..." & winget upgrade --id Git.Git -e @argsCommon | Out-Null } else { Write-Info "Instalando Git..." & winget install --id Git.Git -e @argsCommon | Out-Null } # Garante PATH do git if (-not (Get-Command git -ErrorAction SilentlyContinue)) { $maybeGit = 'C:\Program Files\Git\cmd\git.exe' if (Test-Path $maybeGit) { $env:Path = "C:\Program Files\Git\cmd;$env:Path" } } $ver = git --version 2>$null if (-not $ver) { throw "Git não acessível após instalação/atualização." } Write-Ok "Git pronto: $ver" } function Get-GitTokenEffective { if ($GitToken) { return $GitToken } if ($GitTokenPath) { if (-not (Test-Path -LiteralPath $GitTokenPath)) { throw "Arquivo de token não encontrado: $GitTokenPath" } return (Get-Content -LiteralPath $GitTokenPath -Raw).Trim() } return $null } function Get-BasicAuthHeader([string]$user,[string]$token){ if (-not $user -or -not $token) { return $null } $bytes = [Text.Encoding]::ASCII.GetBytes("$user`:$token") $base64 = [Convert]::ToBase64String($bytes) return "Authorization: Basic $base64" } function Get-GitCommonArgs { param([string]$AuthHeader) # Evita prompts/UI/navegador e askpass $args = @( '-c','credential.helper=', '-c','credential.interactive=never', '-c','core.askPass=' ) # Se fornecer header, usa-o nesta chamada (não grava no .git/config) if ($AuthHeader) { $args += @('-c',"http.extraHeader=$AuthHeader") } return ,$args } # ===== Início ===== try { # Auto-desbloqueia este arquivo (elimina marca de internet se houver) try { Unblock-File -LiteralPath $MyInvocation.MyCommand.Path -ErrorAction SilentlyContinue } catch { } Ensure-Git-WithWinget Ensure-Dir $TargetDir # Prepara credenciais (opcionais) $EffectiveToken = Get-GitTokenEffective if ($GitUser -and -not $EffectiveToken) { Write-Warn "GitUser informado mas nenhum token fornecido. Continuação sem autenticação." } $AuthHeader = $null if ($GitUser -and $EffectiveToken) { $AuthHeader = Get-BasicAuthHeader -user $GitUser -token $EffectiveToken Write-Info "Usando autenticação via header (sem gravar credenciais em .git/config)." } # Nunca abrir prompts/navegador $env:GIT_TERMINAL_PROMPT = '0' # Clone/Update if (Test-Path (Join-Path $WorkDir '.git')) { Write-Info "Atualizando repositório em $WorkDir ..." Push-Location $WorkDir try { & git (Get-GitCommonArgs -AuthHeader $AuthHeader) remote set-url origin $RepoUrl | Out-Null } catch { } & git (Get-GitCommonArgs -AuthHeader $AuthHeader) fetch --all --prune & git (Get-GitCommonArgs -AuthHeader $AuthHeader) checkout $Branch & git (Get-GitCommonArgs -AuthHeader $AuthHeader) reset --hard "origin/$Branch" Pop-Location } else { Write-Info "Clonando repositório (branch $Branch) para $WorkDir ..." try { Remove-Item -LiteralPath $WorkDir -Recurse -Force -ErrorAction SilentlyContinue } catch { } Ensure-Dir $WorkDir & git (Get-GitCommonArgs -AuthHeader $AuthHeader) clone --depth 1 --branch $Branch $RepoUrl $WorkDir Write-Ok "Clone concluído." } # Copiar por cima (sem espelhar) Write-Info "Copiando arquivos para $TargetDir (sem espelhar)..." $rc = robocopy ` $WorkDir ` $TargetDir ` * ` /E /IS /IT /R:1 /W:1 /NFL /NDL /NP ` /XD ".git" ` /XF ".gitignore" ".gitattributes" ` /LOG:$CopyLog if ($LASTEXITCODE -ge 8) { Write-Err "Falha ao copiar arquivos. Veja o log: $CopyLog" exit $LASTEXITCODE } else { Write-Ok "Cópia finalizada. (código robocopy: $LASTEXITCODE) Log: $CopyLog" } # Executa o instalador $InstallScript = Join-Path $TargetDir 'pilot_install.ps1' if (Test-Path -LiteralPath $InstallScript) { Write-Info "Executando $InstallScript ..." try { Unblock-File -LiteralPath $InstallScript -ErrorAction SilentlyContinue } catch { } $p = Start-Process -FilePath 'powershell.exe' -ArgumentList @( '-NoProfile','-ExecutionPolicy','Bypass','-File', $InstallScript ) -Wait -PassThru if ($p.ExitCode -ne 0) { Write-Err "pilot_install.ps1 retornou código $($p.ExitCode)." exit $p.ExitCode } else { Write-Ok "pilot_install.ps1 executado com sucesso." } } else { Write-Warn "Arquivo não encontrado: $InstallScript. Execução ignorada." } Write-Ok "Processo concluído." exit 0 } catch { Write-Err ("Erro: " + $_.Exception.Message) exit 1 } finally { # Limpa variáveis sensíveis do ambiente Remove-Item Env:\GIT_TERMINAL_PROMPT -ErrorAction SilentlyContinue }