Fix Gitea wrapper login resolution #538
@@ -30,6 +30,7 @@ Fix the framework git wrappers so Gitea issue/PR operations resolve the tea logi
|
|||||||
- Updated Gitea issue, PR, milestone, and CI wrappers to use resolved host-specific tea login arguments instead of defaulting to `mosaicstack`.
|
- Updated Gitea issue, PR, milestone, and CI wrappers to use resolved host-specific tea login arguments instead of defaulting to `mosaicstack`.
|
||||||
- Added authenticated API fallbacks for close/reopen paths so wrappers can still operate when a matching `tea` login is absent but token credentials are available.
|
- Added authenticated API fallbacks for close/reopen paths so wrappers can still operate when a matching `tea` login is absent but token credentials are available.
|
||||||
- Added regression coverage for stale `GITEA_LOGIN`, exact host matching, `--repo` override flows, USC issue close routing, mosaicstack API fallback, and PR metadata/merge fallbacks.
|
- Added regression coverage for stale `GITEA_LOGIN`, exact host matching, `--repo` override flows, USC issue close routing, mosaicstack API fallback, and PR metadata/merge fallbacks.
|
||||||
|
- Delta after PR #538 review: extended host-aware login/repo resolution to PowerShell wrappers, Bash milestone wrappers, and API-only `--repo` fallback paths.
|
||||||
|
|
||||||
## Verification
|
## Verification
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ Fix the framework git wrappers so Gitea issue/PR operations resolve the tea logi
|
|||||||
- `packages/mosaic/framework/tools/git/test-gitea-login-resolution.sh`
|
- `packages/mosaic/framework/tools/git/test-gitea-login-resolution.sh`
|
||||||
- `packages/mosaic/framework/tools/git/test-pr-metadata-gitea.sh`
|
- `packages/mosaic/framework/tools/git/test-pr-metadata-gitea.sh`
|
||||||
- `packages/mosaic/framework/tools/git/test-pr-merge-gitea-empty-uid.sh`
|
- `packages/mosaic/framework/tools/git/test-pr-merge-gitea-empty-uid.sh`
|
||||||
|
- `pwsh -NoProfile` parse check for all `packages/mosaic/framework/tools/git/*.ps1`
|
||||||
- `pnpm typecheck`
|
- `pnpm typecheck`
|
||||||
- `pnpm lint`
|
- `pnpm lint`
|
||||||
- `pnpm format:check`
|
- `pnpm format:check`
|
||||||
|
|||||||
@@ -55,6 +55,154 @@ function Get-GitRepoInfo {
|
|||||||
return $repoPath
|
return $repoPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Get-GitRemoteHost {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param()
|
||||||
|
|
||||||
|
$remoteUrl = git remote get-url origin 2>$null
|
||||||
|
|
||||||
|
if ([string]::IsNullOrEmpty($remoteUrl)) {
|
||||||
|
Write-Error "Not a git repository or no origin remote"
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($remoteUrl -match "^https?://([^/]+)/") {
|
||||||
|
$remoteHost = $Matches[1]
|
||||||
|
return ($remoteHost -replace "^.*@", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($remoteUrl -match "^git@([^:]+):") {
|
||||||
|
return $Matches[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-TeaLoginList {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param()
|
||||||
|
|
||||||
|
$json = tea login list --output json 2>$null
|
||||||
|
if (-not $json) {
|
||||||
|
return @()
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$items = $json | ConvertFrom-Json
|
||||||
|
} catch {
|
||||||
|
return @()
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($null -eq $items) {
|
||||||
|
return @()
|
||||||
|
}
|
||||||
|
|
||||||
|
return @($items)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Test-GiteaUrlMatchesHost {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[string]$Url,
|
||||||
|
[string]$GiteaHost
|
||||||
|
)
|
||||||
|
|
||||||
|
if ([string]::IsNullOrEmpty($Url) -or [string]::IsNullOrEmpty($GiteaHost)) {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$uri = [Uri]$Url
|
||||||
|
return $uri.Host -eq $GiteaHost
|
||||||
|
} catch {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Find-TeaLoginForHost {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param([Parameter(Mandatory=$true)][string]$GiteaHost)
|
||||||
|
|
||||||
|
foreach ($login in Get-TeaLoginList) {
|
||||||
|
$name = if ($login.name) { [string]$login.name } elseif ($login.Name) { [string]$login.Name } else { "" }
|
||||||
|
$url = if ($login.url) { [string]$login.url } elseif ($login.URL) { [string]$login.URL } else { "" }
|
||||||
|
if ([string]::IsNullOrEmpty($name) -or [string]::IsNullOrEmpty($url)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$uri = [Uri]$url
|
||||||
|
if ($uri.Host -eq $GiteaHost) {
|
||||||
|
return $name
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
function Test-TeaLoginMatchesHost {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)][string]$LoginName,
|
||||||
|
[Parameter(Mandatory=$true)][string]$GiteaHost
|
||||||
|
)
|
||||||
|
|
||||||
|
foreach ($login in Get-TeaLoginList) {
|
||||||
|
$name = if ($login.name) { [string]$login.name } elseif ($login.Name) { [string]$login.Name } else { "" }
|
||||||
|
$url = if ($login.url) { [string]$login.url } elseif ($login.URL) { [string]$login.URL } else { "" }
|
||||||
|
if ($name -ne $LoginName -or [string]::IsNullOrEmpty($url)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$uri = [Uri]$url
|
||||||
|
return $uri.Host -eq $GiteaHost
|
||||||
|
} catch {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-GiteaLoginForHost {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param([string]$GiteaHost)
|
||||||
|
|
||||||
|
if ([string]::IsNullOrEmpty($GiteaHost)) {
|
||||||
|
$GiteaHost = Get-GitRemoteHost
|
||||||
|
}
|
||||||
|
if ([string]::IsNullOrEmpty($GiteaHost)) {
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($env:GITEA_LOGIN) {
|
||||||
|
if ((Test-GiteaUrlMatchesHost -Url $env:GITEA_URL -GiteaHost $GiteaHost) -or (Test-TeaLoginMatchesHost -LoginName $env:GITEA_LOGIN -GiteaHost $GiteaHost)) {
|
||||||
|
return $env:GITEA_LOGIN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Find-TeaLoginForHost -GiteaHost $GiteaHost
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-GiteaRepoArgs {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param()
|
||||||
|
|
||||||
|
$repo = Get-GitRepoInfo
|
||||||
|
$hostName = Get-GitRemoteHost
|
||||||
|
$login = Get-GiteaLoginForHost -GiteaHost $hostName
|
||||||
|
|
||||||
|
if ([string]::IsNullOrEmpty($repo) -or [string]::IsNullOrEmpty($login)) {
|
||||||
|
return @()
|
||||||
|
}
|
||||||
|
|
||||||
|
return @("--repo", $repo, "--login", $login)
|
||||||
|
}
|
||||||
|
|
||||||
function Get-GitRepoOwner {
|
function Get-GitRepoOwner {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
param()
|
param()
|
||||||
|
|||||||
@@ -248,6 +248,31 @@ get_gitea_login_for_repo_override() {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_host_from_url() {
|
||||||
|
local url="${1:-}"
|
||||||
|
[[ -n "$url" ]] || return 1
|
||||||
|
|
||||||
|
python3 - "$url" <<'PY'
|
||||||
|
import sys
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
parsed = urlparse(sys.argv[1])
|
||||||
|
if parsed.hostname:
|
||||||
|
print(parsed.hostname)
|
||||||
|
raise SystemExit(0)
|
||||||
|
raise SystemExit(1)
|
||||||
|
PY
|
||||||
|
}
|
||||||
|
|
||||||
|
get_gitea_api_host_for_repo_override() {
|
||||||
|
if [[ -n "${GITEA_HOST:-}" ]]; then
|
||||||
|
echo "$GITEA_HOST"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
get_host_from_url "${GITEA_URL:-}"
|
||||||
|
}
|
||||||
|
|
||||||
get_gitea_repo_args() {
|
get_gitea_repo_args() {
|
||||||
local repo host login
|
local repo host login
|
||||||
repo=$(get_repo_slug) || return 1
|
repo=$(get_repo_slug) || return 1
|
||||||
|
|||||||
@@ -75,6 +75,11 @@ switch ($platform) {
|
|||||||
Write-Host "Issue #$Issue updated successfully"
|
Write-Host "Issue #$Issue updated successfully"
|
||||||
}
|
}
|
||||||
"gitea" {
|
"gitea" {
|
||||||
|
$repoArgs = @(Get-GiteaRepoArgs)
|
||||||
|
if ($repoArgs.Length -eq 0) {
|
||||||
|
Write-Error "Could not resolve Gitea repo/login for remote host"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
$needsEdit = $false
|
$needsEdit = $false
|
||||||
$cmd = @("tea", "issue", "edit", $Issue)
|
$cmd = @("tea", "issue", "edit", $Issue)
|
||||||
|
|
||||||
@@ -87,7 +92,7 @@ switch ($platform) {
|
|||||||
$needsEdit = $true
|
$needsEdit = $true
|
||||||
}
|
}
|
||||||
if ($Milestone) {
|
if ($Milestone) {
|
||||||
$milestoneList = tea milestones list 2>$null
|
$milestoneList = tea milestones list @repoArgs 2>$null
|
||||||
$milestoneId = ($milestoneList | Select-String "^\s*(\d+).*$Milestone" | ForEach-Object { $_.Matches.Groups[1].Value } | Select-Object -First 1)
|
$milestoneId = ($milestoneList | Select-String "^\s*(\d+).*$Milestone" | ForEach-Object { $_.Matches.Groups[1].Value } | Select-Object -First 1)
|
||||||
if ($milestoneId) {
|
if ($milestoneId) {
|
||||||
$cmd += @("--milestone", $milestoneId)
|
$cmd += @("--milestone", $milestoneId)
|
||||||
@@ -98,6 +103,7 @@ switch ($platform) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($needsEdit) {
|
if ($needsEdit) {
|
||||||
|
$cmd += $repoArgs
|
||||||
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
||||||
Write-Host "Issue #$Issue updated successfully"
|
Write-Host "Issue #$Issue updated successfully"
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -58,12 +58,17 @@ switch ($platform) {
|
|||||||
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
||||||
}
|
}
|
||||||
"gitea" {
|
"gitea" {
|
||||||
|
$repoArgs = @(Get-GiteaRepoArgs)
|
||||||
|
if ($repoArgs.Length -eq 0) {
|
||||||
|
Write-Error "Could not resolve Gitea repo/login for remote host"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
$cmd = @("tea", "issue", "create", "--title", $Title)
|
$cmd = @("tea", "issue", "create", "--title", $Title)
|
||||||
if ($Body) { $cmd += @("--description", $Body) }
|
if ($Body) { $cmd += @("--description", $Body) }
|
||||||
if ($Labels) { $cmd += @("--labels", $Labels) }
|
if ($Labels) { $cmd += @("--labels", $Labels) }
|
||||||
if ($Milestone) {
|
if ($Milestone) {
|
||||||
# Try to get milestone ID by name
|
# Try to get milestone ID by name
|
||||||
$milestoneList = tea milestones list 2>$null
|
$milestoneList = tea milestones list @repoArgs 2>$null
|
||||||
$milestoneId = ($milestoneList | Select-String "^\s*(\d+).*$Milestone" | ForEach-Object { $_.Matches.Groups[1].Value } | Select-Object -First 1)
|
$milestoneId = ($milestoneList | Select-String "^\s*(\d+).*$Milestone" | ForEach-Object { $_.Matches.Groups[1].Value } | Select-Object -First 1)
|
||||||
if ($milestoneId) {
|
if ($milestoneId) {
|
||||||
$cmd += @("--milestone", $milestoneId)
|
$cmd += @("--milestone", $milestoneId)
|
||||||
@@ -71,6 +76,7 @@ switch ($platform) {
|
|||||||
Write-Warning "Could not find milestone '$Milestone', creating without milestone"
|
Write-Warning "Could not find milestone '$Milestone', creating without milestone"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$cmd += $repoArgs
|
||||||
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
||||||
}
|
}
|
||||||
default {
|
default {
|
||||||
|
|||||||
@@ -63,9 +63,15 @@ switch ($platform) {
|
|||||||
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
||||||
}
|
}
|
||||||
"gitea" {
|
"gitea" {
|
||||||
|
$repoArgs = @(Get-GiteaRepoArgs)
|
||||||
|
if ($repoArgs.Length -eq 0) {
|
||||||
|
Write-Error "Could not resolve Gitea repo/login for remote host"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
$cmd = @("tea", "issues", "list", "--state", $State, "--limit", $Limit)
|
$cmd = @("tea", "issues", "list", "--state", $State, "--limit", $Limit)
|
||||||
if ($Label) { $cmd += @("--labels", $Label) }
|
if ($Label) { $cmd += @("--labels", $Label) }
|
||||||
if ($Milestone) { $cmd += @("--milestones", $Milestone) }
|
if ($Milestone) { $cmd += @("--milestones", $Milestone) }
|
||||||
|
$cmd += $repoArgs
|
||||||
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
||||||
if ($Assignee) {
|
if ($Assignee) {
|
||||||
Write-Warning "Assignee filtering may require manual review for Gitea"
|
Write-Warning "Assignee filtering may require manual review for Gitea"
|
||||||
|
|||||||
@@ -42,7 +42,11 @@ if [[ "$PLATFORM" == "github" ]]; then
|
|||||||
gh api -X PATCH "/repos/{owner}/{repo}/milestones/$(gh api "/repos/{owner}/{repo}/milestones" --jq ".[] | select(.title==\"$TITLE\") | .number")" -f state=closed
|
gh api -X PATCH "/repos/{owner}/{repo}/milestones/$(gh api "/repos/{owner}/{repo}/milestones" --jq ".[] | select(.title==\"$TITLE\") | .number")" -f state=closed
|
||||||
echo "Closed GitHub milestone: $TITLE"
|
echo "Closed GitHub milestone: $TITLE"
|
||||||
elif [[ "$PLATFORM" == "gitea" ]]; then
|
elif [[ "$PLATFORM" == "gitea" ]]; then
|
||||||
tea milestone close "$TITLE"
|
REPO_ARGS=$(get_gitea_repo_args) || {
|
||||||
|
echo "Error: Could not resolve Gitea repo/login for remote host" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
tea milestone close "$TITLE" $REPO_ARGS
|
||||||
echo "Closed Gitea milestone: $TITLE"
|
echo "Closed Gitea milestone: $TITLE"
|
||||||
else
|
else
|
||||||
echo "Error: Unknown platform"
|
echo "Error: Unknown platform"
|
||||||
|
|||||||
@@ -59,7 +59,12 @@ if ($List) {
|
|||||||
gh api repos/:owner/:repo/milestones --jq '.[] | "\(.number)`t\(.title)`t\(.state)`t\(.open_issues)/\(.closed_issues) issues"'
|
gh api repos/:owner/:repo/milestones --jq '.[] | "\(.number)`t\(.title)`t\(.state)`t\(.open_issues)/\(.closed_issues) issues"'
|
||||||
}
|
}
|
||||||
"gitea" {
|
"gitea" {
|
||||||
tea milestones list
|
$repoArgs = @(Get-GiteaRepoArgs)
|
||||||
|
if ($repoArgs.Length -eq 0) {
|
||||||
|
Write-Error "Could not resolve Gitea repo/login for remote host"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
tea milestones list @repoArgs
|
||||||
}
|
}
|
||||||
default {
|
default {
|
||||||
Write-Error "Could not detect git platform"
|
Write-Error "Could not detect git platform"
|
||||||
@@ -85,9 +90,15 @@ switch ($platform) {
|
|||||||
Write-Host "Milestone '$Title' created successfully"
|
Write-Host "Milestone '$Title' created successfully"
|
||||||
}
|
}
|
||||||
"gitea" {
|
"gitea" {
|
||||||
|
$repoArgs = @(Get-GiteaRepoArgs)
|
||||||
|
if ($repoArgs.Length -eq 0) {
|
||||||
|
Write-Error "Could not resolve Gitea repo/login for remote host"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
$cmd = @("tea", "milestones", "create", "--title", $Title)
|
$cmd = @("tea", "milestones", "create", "--title", $Title)
|
||||||
if ($Description) { $cmd += @("--description", $Description) }
|
if ($Description) { $cmd += @("--description", $Description) }
|
||||||
if ($Due) { $cmd += @("--deadline", $Due) }
|
if ($Due) { $cmd += @("--deadline", $Due) }
|
||||||
|
$cmd += $repoArgs
|
||||||
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
||||||
Write-Host "Milestone '$Title' created successfully"
|
Write-Host "Milestone '$Title' created successfully"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ if [[ "$LIST_ONLY" == true ]]; then
|
|||||||
gh api repos/:owner/:repo/milestones --jq '.[] | "\(.number)\t\(.title)\t\(.state)\t\(.open_issues)/\(.closed_issues) issues"'
|
gh api repos/:owner/:repo/milestones --jq '.[] | "\(.number)\t\(.title)\t\(.state)\t\(.open_issues)/\(.closed_issues) issues"'
|
||||||
;;
|
;;
|
||||||
gitea)
|
gitea)
|
||||||
tea milestones list
|
REPO_ARGS=$(get_gitea_repo_args) || {
|
||||||
|
echo "Error: Could not resolve Gitea repo/login for remote host" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
tea milestones list $REPO_ARGS
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Error: Could not detect git platform" >&2
|
echo "Error: Could not detect git platform" >&2
|
||||||
@@ -104,10 +108,14 @@ case "$PLATFORM" in
|
|||||||
echo "Milestone '$TITLE' created successfully"
|
echo "Milestone '$TITLE' created successfully"
|
||||||
;;
|
;;
|
||||||
gitea)
|
gitea)
|
||||||
CMD="tea milestones create --title \"$TITLE\""
|
REPO_ARGS=$(get_gitea_repo_args) || {
|
||||||
[[ -n "$DESCRIPTION" ]] && CMD="$CMD --description \"$DESCRIPTION\""
|
echo "Error: Could not resolve Gitea repo/login for remote host" >&2
|
||||||
[[ -n "$DUE_DATE" ]] && CMD="$CMD --deadline \"$DUE_DATE\""
|
exit 1
|
||||||
eval "$CMD"
|
}
|
||||||
|
CMD=(tea milestones create --title "$TITLE")
|
||||||
|
[[ -n "$DESCRIPTION" ]] && CMD+=(--description "$DESCRIPTION")
|
||||||
|
[[ -n "$DUE_DATE" ]] && CMD+=(--deadline "$DUE_DATE")
|
||||||
|
"${CMD[@]}" $REPO_ARGS
|
||||||
echo "Milestone '$TITLE' created successfully"
|
echo "Milestone '$TITLE' created successfully"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
|||||||
@@ -36,7 +36,11 @@ detect_platform >/dev/null
|
|||||||
if [[ "$PLATFORM" == "github" ]]; then
|
if [[ "$PLATFORM" == "github" ]]; then
|
||||||
gh api "/repos/{owner}/{repo}/milestones?state=$STATE" --jq '.[] | "\(.title) (\(.state)) - \(.open_issues) open, \(.closed_issues) closed"'
|
gh api "/repos/{owner}/{repo}/milestones?state=$STATE" --jq '.[] | "\(.title) (\(.state)) - \(.open_issues) open, \(.closed_issues) closed"'
|
||||||
elif [[ "$PLATFORM" == "gitea" ]]; then
|
elif [[ "$PLATFORM" == "gitea" ]]; then
|
||||||
tea milestone list
|
REPO_ARGS=$(get_gitea_repo_args) || {
|
||||||
|
echo "Error: Could not resolve Gitea repo/login for remote host" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
tea milestone list $REPO_ARGS
|
||||||
else
|
else
|
||||||
echo "Error: Unknown platform"
|
echo "Error: Unknown platform"
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ PR_NUMBER=""
|
|||||||
TIMEOUT_SEC=1800
|
TIMEOUT_SEC=1800
|
||||||
INTERVAL_SEC=15
|
INTERVAL_SEC=15
|
||||||
REPO_OVERRIDE=""
|
REPO_OVERRIDE=""
|
||||||
|
HOST_OVERRIDE=""
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
@@ -19,6 +20,7 @@ Usage: $(basename "$0") -n <pr_number> [-t timeout_sec] [-i interval_sec]
|
|||||||
Options:
|
Options:
|
||||||
-n, --number NUMBER PR number (required)
|
-n, --number NUMBER PR number (required)
|
||||||
-r, --repo OWNER/REPO Repository slug (default: infer from git origin)
|
-r, --repo OWNER/REPO Repository slug (default: infer from git origin)
|
||||||
|
--host HOST Gitea host for --repo API calls (or set GITEA_HOST/GITEA_URL)
|
||||||
-t, --timeout SECONDS Max wait time in seconds (default: 1800)
|
-t, --timeout SECONDS Max wait time in seconds (default: 1800)
|
||||||
-i, --interval SECONDS Poll interval in seconds (default: 15)
|
-i, --interval SECONDS Poll interval in seconds (default: 15)
|
||||||
-h, --help Show this help
|
-h, --help Show this help
|
||||||
@@ -150,6 +152,10 @@ while [[ $# -gt 0 ]]; do
|
|||||||
REPO_OVERRIDE="$2"
|
REPO_OVERRIDE="$2"
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
|
--host)
|
||||||
|
HOST_OVERRIDE="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
-t|--timeout)
|
-t|--timeout)
|
||||||
TIMEOUT_SEC="$2"
|
TIMEOUT_SEC="$2"
|
||||||
shift 2
|
shift 2
|
||||||
@@ -211,7 +217,19 @@ if [[ "$PLATFORM" == "github" ]]; then
|
|||||||
fi
|
fi
|
||||||
echo "[pr-ci-wait] Platform=github PR=#${PR_NUMBER} head_sha=${HEAD_SHA}"
|
echo "[pr-ci-wait] Platform=github PR=#${PR_NUMBER} head_sha=${HEAD_SHA}"
|
||||||
elif [[ "$PLATFORM" == "gitea" ]]; then
|
elif [[ "$PLATFORM" == "gitea" ]]; then
|
||||||
HOST=$(get_remote_host 2>/dev/null || echo "git.mosaicstack.dev")
|
if [[ -n "$HOST_OVERRIDE" ]]; then
|
||||||
|
HOST="$HOST_OVERRIDE"
|
||||||
|
elif [[ -n "$REPO_OVERRIDE" ]]; then
|
||||||
|
HOST=$(get_gitea_api_host_for_repo_override) || {
|
||||||
|
echo "Error: Gitea host is required with --repo. Pass --host or set GITEA_HOST/GITEA_URL." >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
HOST=$(get_remote_host) || {
|
||||||
|
echo "Error: Could not determine Gitea host from git origin." >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
fi
|
||||||
TOKEN=$(get_gitea_token "$HOST") || {
|
TOKEN=$(get_gitea_token "$HOST") || {
|
||||||
echo "Error: Gitea token not found. Set GITEA_TOKEN or configure ~/.git-credentials." >&2
|
echo "Error: Gitea token not found. Set GITEA_TOKEN or configure ~/.git-credentials." >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ param(
|
|||||||
[Alias("b")]
|
[Alias("b")]
|
||||||
[string]$Body,
|
[string]$Body,
|
||||||
|
|
||||||
[Alias("B")]
|
|
||||||
[string]$Base,
|
[string]$Base,
|
||||||
|
|
||||||
[Alias("H")]
|
[Alias("H")]
|
||||||
@@ -101,6 +100,11 @@ switch ($platform) {
|
|||||||
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
||||||
}
|
}
|
||||||
"gitea" {
|
"gitea" {
|
||||||
|
$repoArgs = @(Get-GiteaRepoArgs)
|
||||||
|
if ($repoArgs.Length -eq 0) {
|
||||||
|
Write-Error "Could not resolve Gitea repo/login for remote host"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
$cmd = @("tea", "pr", "create", "--title", $Title)
|
$cmd = @("tea", "pr", "create", "--title", $Title)
|
||||||
if ($Body) { $cmd += @("--description", $Body) }
|
if ($Body) { $cmd += @("--description", $Body) }
|
||||||
if ($Base) { $cmd += @("--base", $Base) }
|
if ($Base) { $cmd += @("--base", $Base) }
|
||||||
@@ -108,7 +112,7 @@ switch ($platform) {
|
|||||||
if ($Labels) { $cmd += @("--labels", $Labels) }
|
if ($Labels) { $cmd += @("--labels", $Labels) }
|
||||||
|
|
||||||
if ($Milestone) {
|
if ($Milestone) {
|
||||||
$milestoneList = tea milestones list 2>$null
|
$milestoneList = tea milestones list @repoArgs 2>$null
|
||||||
$milestoneId = ($milestoneList | Select-String "^\s*(\d+).*$Milestone" | ForEach-Object { $_.Matches.Groups[1].Value } | Select-Object -First 1)
|
$milestoneId = ($milestoneList | Select-String "^\s*(\d+).*$Milestone" | ForEach-Object { $_.Matches.Groups[1].Value } | Select-Object -First 1)
|
||||||
if ($milestoneId) {
|
if ($milestoneId) {
|
||||||
$cmd += @("--milestone", $milestoneId)
|
$cmd += @("--milestone", $milestoneId)
|
||||||
@@ -121,6 +125,7 @@ switch ($platform) {
|
|||||||
Write-Warning "Draft PR may not be supported by your tea version"
|
Write-Warning "Draft PR may not be supported by your tea version"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$cmd += $repoArgs
|
||||||
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
||||||
}
|
}
|
||||||
default {
|
default {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ source "$SCRIPT_DIR/detect-platform.sh"
|
|||||||
PR_NUMBER=""
|
PR_NUMBER=""
|
||||||
OUTPUT_FILE=""
|
OUTPUT_FILE=""
|
||||||
REPO_OVERRIDE=""
|
REPO_OVERRIDE=""
|
||||||
|
HOST_OVERRIDE=""
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
case $1 in
|
case $1 in
|
||||||
@@ -26,12 +27,17 @@ while [[ $# -gt 0 ]]; do
|
|||||||
REPO_OVERRIDE="$2"
|
REPO_OVERRIDE="$2"
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
|
--host)
|
||||||
|
HOST_OVERRIDE="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
-h|--help)
|
-h|--help)
|
||||||
echo "Usage: pr-diff.sh -n <pr_number> [-r owner/repo] [-o <output_file>]"
|
echo "Usage: pr-diff.sh -n <pr_number> [-r owner/repo] [--host host] [-o <output_file>]"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Options:"
|
echo "Options:"
|
||||||
echo " -n, --number PR number (required)"
|
echo " -n, --number PR number (required)"
|
||||||
echo " -r, --repo Repository slug (default: infer from git origin)"
|
echo " -r, --repo Repository slug (default: infer from git origin)"
|
||||||
|
echo " --host Gitea host for --repo API calls (or set GITEA_HOST/GITEA_URL)"
|
||||||
echo " -o, --output Output file (optional, prints to stdout if omitted)"
|
echo " -o, --output Output file (optional, prints to stdout if omitted)"
|
||||||
echo " -h, --help Show this help"
|
echo " -h, --help Show this help"
|
||||||
exit 0
|
exit 0
|
||||||
@@ -69,7 +75,19 @@ if [[ "$PLATFORM" == "github" ]]; then
|
|||||||
fi
|
fi
|
||||||
elif [[ "$PLATFORM" == "gitea" ]]; then
|
elif [[ "$PLATFORM" == "gitea" ]]; then
|
||||||
# tea doesn't have a direct diff command — use the API
|
# tea doesn't have a direct diff command — use the API
|
||||||
HOST=$(get_remote_host 2>/dev/null || echo "git.mosaicstack.dev")
|
if [[ -n "$HOST_OVERRIDE" ]]; then
|
||||||
|
HOST="$HOST_OVERRIDE"
|
||||||
|
elif [[ -n "$REPO_OVERRIDE" ]]; then
|
||||||
|
HOST=$(get_gitea_api_host_for_repo_override) || {
|
||||||
|
echo "Error: Gitea host is required with --repo. Pass --host or set GITEA_HOST/GITEA_URL." >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
HOST=$(get_remote_host) || {
|
||||||
|
echo "Error: Could not determine Gitea host from git origin." >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
DIFF_URL="https://${HOST}/api/v1/repos/${REPO_INFO}/pulls/${PR_NUMBER}.diff"
|
DIFF_URL="https://${HOST}/api/v1/repos/${REPO_INFO}/pulls/${PR_NUMBER}.diff"
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,11 @@ switch ($platform) {
|
|||||||
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
||||||
}
|
}
|
||||||
"gitea" {
|
"gitea" {
|
||||||
|
$repoArgs = @(Get-GiteaRepoArgs)
|
||||||
|
if ($repoArgs.Length -eq 0) {
|
||||||
|
Write-Error "Could not resolve Gitea repo/login for remote host"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
$cmd = @("tea", "pr", "list", "--state", $State, "--limit", $Limit)
|
$cmd = @("tea", "pr", "list", "--state", $State, "--limit", $Limit)
|
||||||
|
|
||||||
if ($Label) {
|
if ($Label) {
|
||||||
@@ -67,6 +72,7 @@ switch ($platform) {
|
|||||||
Write-Warning "Author filtering may require manual review for Gitea"
|
Write-Warning "Author filtering may require manual review for Gitea"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$cmd += $repoArgs
|
||||||
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
||||||
}
|
}
|
||||||
default {
|
default {
|
||||||
|
|||||||
@@ -74,6 +74,11 @@ switch ($platform) {
|
|||||||
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
||||||
}
|
}
|
||||||
"gitea" {
|
"gitea" {
|
||||||
|
$repoArgs = @(Get-GiteaRepoArgs)
|
||||||
|
if ($repoArgs.Length -eq 0) {
|
||||||
|
Write-Error "Could not resolve Gitea repo/login for remote host"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
if (-not $SkipQueueGuard) {
|
if (-not $SkipQueueGuard) {
|
||||||
$timeout = if ($env:MOSAIC_CI_QUEUE_TIMEOUT_SEC) { [int]$env:MOSAIC_CI_QUEUE_TIMEOUT_SEC } else { 900 }
|
$timeout = if ($env:MOSAIC_CI_QUEUE_TIMEOUT_SEC) { [int]$env:MOSAIC_CI_QUEUE_TIMEOUT_SEC } else { 900 }
|
||||||
$interval = if ($env:MOSAIC_CI_QUEUE_POLL_SEC) { [int]$env:MOSAIC_CI_QUEUE_POLL_SEC } else { 15 }
|
$interval = if ($env:MOSAIC_CI_QUEUE_POLL_SEC) { [int]$env:MOSAIC_CI_QUEUE_POLL_SEC } else { 15 }
|
||||||
@@ -87,6 +92,7 @@ switch ($platform) {
|
|||||||
Write-Warning "Branch deletion after merge may need to be done separately with tea"
|
Write-Warning "Branch deletion after merge may need to be done separately with tea"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$cmd += $repoArgs
|
||||||
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
& $cmd[0] $cmd[1..($cmd.Length-1)]
|
||||||
}
|
}
|
||||||
default {
|
default {
|
||||||
|
|||||||
@@ -54,7 +54,21 @@ cat > "$BIN_DIR/curl" <<'SH'
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
printf 'curl %s\n' "$*" >> "$MOSAIC_TEST_LOG"
|
printf 'curl %s\n' "$*" >> "$MOSAIC_TEST_LOG"
|
||||||
|
url="${*: -1}"
|
||||||
|
case "$url" in
|
||||||
|
*/pulls/*.diff)
|
||||||
|
printf 'diff --git a/file b/file\n'
|
||||||
|
;;
|
||||||
|
*/pulls/*)
|
||||||
|
printf '{"head":{"sha":"abc123"}}'
|
||||||
|
;;
|
||||||
|
*/commits/*/status)
|
||||||
|
printf '{"state":"success","statuses":[{"context":"ci/mock","status":"success"}]}'
|
||||||
|
;;
|
||||||
|
*)
|
||||||
printf '{}'
|
printf '{}'
|
||||||
|
;;
|
||||||
|
esac
|
||||||
SH
|
SH
|
||||||
|
|
||||||
chmod +x "$BIN_DIR/tea" "$BIN_DIR/curl"
|
chmod +x "$BIN_DIR/tea" "$BIN_DIR/curl"
|
||||||
@@ -126,6 +140,63 @@ if grep -q -- '--login mosaicstack' "$LOG_FILE"; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
: > "$LOG_FILE"
|
||||||
|
run_in_repo "$SCRIPT_DIR/milestone-list.sh"
|
||||||
|
grep -q -- 'tea milestone list --repo USC/uconnect --login usc' "$LOG_FILE"
|
||||||
|
|
||||||
|
: > "$LOG_FILE"
|
||||||
|
run_in_repo "$SCRIPT_DIR/milestone-create.sh" -t "0.2.0" -d "USC milestone"
|
||||||
|
grep -q -- 'tea milestones create --title 0.2.0 --description USC milestone --repo USC/uconnect --login usc' "$LOG_FILE"
|
||||||
|
|
||||||
|
: > "$LOG_FILE"
|
||||||
|
run_in_repo "$SCRIPT_DIR/milestone-close.sh" -t "0.2.0"
|
||||||
|
grep -q -- 'tea milestone close 0.2.0 --repo USC/uconnect --login usc' "$LOG_FILE"
|
||||||
|
|
||||||
|
if command -v pwsh >/dev/null 2>&1; then
|
||||||
|
: > "$LOG_FILE"
|
||||||
|
run_in_repo pwsh -NoProfile -File "$SCRIPT_DIR/issue-list.ps1" -Limit 1
|
||||||
|
grep -q -- 'tea issues list --state open --limit 1 --repo USC/uconnect --login usc' "$LOG_FILE"
|
||||||
|
|
||||||
|
: > "$LOG_FILE"
|
||||||
|
run_in_repo pwsh -NoProfile -File "$SCRIPT_DIR/issue-create.ps1" -Title "PowerShell issue"
|
||||||
|
grep -q -- 'tea issue create --title PowerShell issue --repo USC/uconnect --login usc' "$LOG_FILE"
|
||||||
|
|
||||||
|
: > "$LOG_FILE"
|
||||||
|
run_in_repo pwsh -NoProfile -File "$SCRIPT_DIR/pr-list.ps1" -Limit 1
|
||||||
|
grep -q -- 'tea pr list --state open --limit 1 --repo USC/uconnect --login usc' "$LOG_FILE"
|
||||||
|
|
||||||
|
: > "$LOG_FILE"
|
||||||
|
run_in_repo pwsh -NoProfile -File "$SCRIPT_DIR/pr-create.ps1" -Title "PowerShell PR"
|
||||||
|
grep -q -- 'tea pr create --title PowerShell PR --head master --repo USC/uconnect --login usc' "$LOG_FILE"
|
||||||
|
|
||||||
|
: > "$LOG_FILE"
|
||||||
|
run_in_repo pwsh -NoProfile -File "$SCRIPT_DIR/pr-merge.ps1" -Number 42 -SkipQueueGuard
|
||||||
|
grep -q -- 'tea pr merge 42 --style squash --repo USC/uconnect --login usc' "$LOG_FILE"
|
||||||
|
|
||||||
|
: > "$LOG_FILE"
|
||||||
|
run_in_repo pwsh -NoProfile -File "$SCRIPT_DIR/milestone-create.ps1" -List
|
||||||
|
grep -q -- 'tea milestones list --repo USC/uconnect --login usc' "$LOG_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
: > "$LOG_FILE"
|
||||||
|
if run_in_repo "$SCRIPT_DIR/pr-diff.sh" --repo USC/uconnect -n 7 >/dev/null 2>&1; then
|
||||||
|
echo "Expected pr-diff.sh --repo without host to fail loud" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if grep -q -- 'git.mosaicstack.dev/api/v1/repos/USC/uconnect' "$LOG_FILE"; then
|
||||||
|
echo "pr-diff.sh --repo defaulted API host to git.mosaicstack.dev" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
: > "$LOG_FILE"
|
||||||
|
run_in_repo env GITEA_URL=https://git.uscllc.com "$SCRIPT_DIR/pr-diff.sh" --repo USC/uconnect -n 7 >/dev/null
|
||||||
|
grep -q -- 'curl .*https://git.uscllc.com/api/v1/repos/USC/uconnect/pulls/7.diff' "$LOG_FILE"
|
||||||
|
|
||||||
|
: > "$LOG_FILE"
|
||||||
|
run_in_repo "$SCRIPT_DIR/pr-ci-wait.sh" --repo USC/uconnect --host git.uscllc.com -n 9 -t 2 -i 1
|
||||||
|
grep -q -- 'curl .*https://git.uscllc.com/api/v1/repos/USC/uconnect/pulls/9' "$LOG_FILE"
|
||||||
|
grep -q -- 'curl .*https://git.uscllc.com/api/v1/repos/USC/uconnect/commits/abc123/status' "$LOG_FILE"
|
||||||
|
|
||||||
git -C "$REPO_DIR" remote set-url origin https://git.mosaicstack.dev/mosaicstack/stack.git
|
git -C "$REPO_DIR" remote set-url origin https://git.mosaicstack.dev/mosaicstack/stack.git
|
||||||
: > "$LOG_FILE"
|
: > "$LOG_FILE"
|
||||||
run_in_repo env GITEA_TOKEN=mosaic-token GITEA_URL=https://git.mosaicstack.dev "$SCRIPT_DIR/issue-close.sh" -i 536
|
run_in_repo env GITEA_TOKEN=mosaic-token GITEA_URL=https://git.mosaicstack.dev "$SCRIPT_DIR/issue-close.sh" -i 536
|
||||||
|
|||||||
Reference in New Issue
Block a user