-
Notifications
You must be signed in to change notification settings - Fork 247
feat(core): zero-config GitHub Actions setup for Maester apps (#1503) #1777
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
kayasax
wants to merge
6
commits into
maester365:main
Choose a base branch
from
kayasax:feat/github-setup-automation
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
6226c7e
feat(core): zero-config GitHub Actions setup for Maester apps
kayasax db588d4
fix(internal): add UTF-8 BOM to Set-MtGitHubActionsSecret.ps1
kayasax 024fa3a
Merge branch 'main' into feat/github-setup-automation
SamErde de92976
fix(core): address PR #1777 review feedback
kayasax 0eca764
fix(core): address follow-up Copilot review on PR #1777
kayasax 27562e0
Merge branch 'main' into feat/github-setup-automation
SamErde File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| function Get-MtGitHubRepoFromGit { | ||
| <# | ||
| .SYNOPSIS | ||
| Detects the current GitHub repository from the local git remote (origin). | ||
|
|
||
| .DESCRIPTION | ||
| Used by Add-MtMaesterAppFederatedCredential and New-MtMaesterApp to remove | ||
| the need for the user to specify -GitHubOrganization and -GitHubRepository | ||
| when running the command from inside a git working tree whose `origin` remote | ||
| points at GitHub. | ||
|
|
||
| Supports HTTPS, scp-style SSH, and ssh:// remote URL formats: | ||
| https://github.com/owner/repo.git | ||
| https://github.com/owner/repo | ||
| https://www.github.com/owner/repo.git | ||
| git@github.com:owner/repo.git | ||
| ssh://git@github.com/owner/repo.git | ||
|
|
||
| Returns $null when: | ||
| * git is not installed / not on PATH | ||
| * the current directory is not inside a git working tree | ||
| * the origin remote is not a GitHub URL | ||
| * the URL cannot be parsed | ||
|
|
||
| .OUTPUTS | ||
| [pscustomobject] with Organization, Repository, RemoteUrl properties, or $null. | ||
| #> | ||
| [CmdletBinding()] | ||
| [OutputType([pscustomobject])] | ||
| param( | ||
| # Optional override for the git remote name. Defaults to 'origin'. | ||
| [string] $RemoteName = 'origin' | ||
| ) | ||
|
|
||
| if (-not (Get-Command git -ErrorAction SilentlyContinue)) { | ||
| Write-Verbose "git is not available on PATH; cannot auto-detect GitHub repo." | ||
| return $null | ||
| } | ||
|
|
||
| try { | ||
| $remoteUrl = (& git remote get-url $RemoteName 2>$null) | Select-Object -First 1 | ||
| } catch { | ||
| Write-Verbose "Failed to read git remote '$RemoteName': $($_.Exception.Message)" | ||
| return $null | ||
| } | ||
|
|
||
| if ([string]::IsNullOrWhiteSpace($remoteUrl)) { | ||
| Write-Verbose "git remote '$RemoteName' is not configured." | ||
| return $null | ||
| } | ||
|
|
||
| # Match HTTPS, SSH, and scp-style GitHub URLs. Host anchored to github.com (optional 'www.') | ||
| # so lookalikes such as 'evilgithub.com' or 'github.com.attacker.com' do not match. | ||
| $pattern = '^(?:https?://(?:www\.)?github\.com/|git@github\.com:|ssh://git@github\.com/)([^/]+)/([^/]+?)(?:\.git)?/?\s*$' | ||
| if ($remoteUrl -notmatch $pattern) { | ||
| Write-Verbose "Remote URL '$remoteUrl' is not a recognised GitHub URL." | ||
| return $null | ||
| } | ||
|
|
||
| return [pscustomobject]@{ | ||
| Organization = $Matches[1] | ||
| Repository = $Matches[2] | ||
| RemoteUrl = $remoteUrl.Trim() | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| function Set-MtGitHubActionsSecret { | ||
| <# | ||
| .SYNOPSIS | ||
| Sets AZURE_CLIENT_ID and AZURE_TENANT_ID as GitHub Actions repository secrets via the GitHub CLI. | ||
|
|
||
| .DESCRIPTION | ||
| Used by Add-MtMaesterAppFederatedCredential when -SetGitHubSecrets is specified. | ||
| Returns $true when both secrets were set successfully, $false otherwise (caller | ||
| should fall back to printing manual setup instructions). | ||
|
|
||
| Requires the GitHub CLI (`gh`) to be installed and authenticated. Will validate | ||
| both before attempting any state-changing call. | ||
|
|
||
| .OUTPUTS | ||
| [bool] - $true on success, $false if gh is missing/unauthenticated or any | ||
| `gh secret set` call fails. | ||
| #> | ||
| [CmdletBinding()] | ||
| [OutputType([bool])] | ||
| [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Colors are beautiful')] | ||
| [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'User opted in via -SetGitHubSecrets switch on the calling cmdlet')] | ||
| param( | ||
| # Target repository in 'owner/repo' format. | ||
| [Parameter(Mandatory = $true)] | ||
| [string] $GitHubRepository, | ||
|
|
||
| # Application (Client) ID to store as AZURE_CLIENT_ID. | ||
| [Parameter(Mandatory = $true)] | ||
| [string] $ClientId, | ||
|
|
||
| # Entra Tenant ID to store as AZURE_TENANT_ID. | ||
| [Parameter(Mandatory = $true)] | ||
| [string] $TenantId | ||
| ) | ||
|
|
||
| if (-not (Get-Command gh -ErrorAction SilentlyContinue)) { | ||
| Write-Warning "GitHub CLI ('gh') is not installed or not on PATH. Falling back to manual instructions." | ||
| Write-Host "Install gh from https://cli.github.com/ to enable -SetGitHubSecrets." -ForegroundColor DarkGray | ||
| return $false | ||
| } | ||
|
|
||
| # Validate gh auth - 'gh auth status' exits 0 when authenticated. | ||
| & gh auth status 2>&1 | Out-Null | ||
| if ($LASTEXITCODE -ne 0) { | ||
| Write-Warning "GitHub CLI is not authenticated. Run 'gh auth login' first. Falling back to manual instructions." | ||
| return $false | ||
|
SamErde marked this conversation as resolved.
|
||
| } | ||
|
|
||
| Write-Host "Setting GitHub Actions secrets on $GitHubRepository via gh CLI..." -ForegroundColor Yellow | ||
|
|
||
| $secrets = [ordered]@{ | ||
| AZURE_CLIENT_ID = $ClientId | ||
| AZURE_TENANT_ID = $TenantId | ||
|
SamErde marked this conversation as resolved.
|
||
| } | ||
|
|
||
| foreach ($name in $secrets.Keys) { | ||
| $value = $secrets[$name] | ||
| # Pipe the value via stdin so the secret never appears on the gh command line | ||
| # (process listings, audit logs, shell history would otherwise capture it). | ||
| $output = $value | & gh secret set $name --repo $GitHubRepository 2>&1 | ||
| if ($LASTEXITCODE -ne 0) { | ||
| Write-Warning "Failed to set $name on $GitHubRepository : $output" | ||
| return $false | ||
| } | ||
| Write-Host " ✓ $name set" -ForegroundColor Green | ||
| } | ||
|
|
||
| Write-Host "" | ||
| Write-Host "✅ AZURE_CLIENT_ID and AZURE_TENANT_ID configured on $GitHubRepository." -ForegroundColor Green | ||
| Write-Host "" | ||
| return $true | ||
| } | ||
46 changes: 46 additions & 0 deletions
46
powershell/internal/Write-MtGitHubSecretsManualInstruction.ps1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| function Write-MtGitHubSecretsManualInstruction { | ||
| <# | ||
| .SYNOPSIS | ||
| Prints the manual GitHub Actions secrets setup instructions used as a fallback by | ||
| Add-MtMaesterAppFederatedCredential when -SetGitHubSecrets is not used or when the | ||
| GitHub CLI (`gh`) is unavailable / unauthenticated / fails. | ||
| #> | ||
| [CmdletBinding()] | ||
| [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Colors are beautiful')] | ||
| param( | ||
| [Parameter(Mandatory = $true)] [string] $GitHubOrganization, | ||
| [Parameter(Mandatory = $true)] [string] $GitHubRepository, | ||
| [Parameter(Mandatory = $true)] [string] $ClientId, | ||
| [Parameter(Mandatory = $true)] [string] $TenantId, | ||
|
|
||
| # When $true the caller already attempted -SetGitHubSecrets and the gh CLI path | ||
| # failed (missing / unauthenticated / call failure). In that case suggesting the | ||
| # user re-run with the same switch is misleading - show a `gh` troubleshooting tip | ||
| # instead. | ||
| [switch] $AttemptedAutomatic | ||
| ) | ||
|
|
||
| $githubSecretsUrl = "https://github.com/$GitHubOrganization/$GitHubRepository/settings/secrets/actions" | ||
|
|
||
| Write-Host "GitHub Actions Configuration:" -ForegroundColor Yellow | ||
| Write-Host "Add these secrets to your GitHub repository ($GitHubOrganization/$GitHubRepository):" -ForegroundColor White | ||
| Write-Host "" | ||
| Write-Host "1. Browse to $githubSecretsUrl" -ForegroundColor Cyan | ||
| Write-Host "2. Click on 'New repository secret'" -ForegroundColor Cyan | ||
| Write-Host "3. Create the following secrets:" -ForegroundColor Cyan | ||
| Write-Host "" | ||
| Write-Host " Name: AZURE_CLIENT_ID" -ForegroundColor Cyan | ||
| Write-Host " Value: $ClientId" -ForegroundColor Cyan | ||
| Write-Host " Name: AZURE_TENANT_ID" -ForegroundColor Cyan | ||
| Write-Host " Value: $TenantId" -ForegroundColor Cyan | ||
| Write-Host "" | ||
| if ($AttemptedAutomatic) { | ||
| Write-Host "Tip: -SetGitHubSecrets was requested but the GitHub CLI ('gh') was unavailable or" -ForegroundColor DarkGray | ||
| Write-Host " failed. Install gh from https://cli.github.com/, run 'gh auth login', then re-run" -ForegroundColor DarkGray | ||
| Write-Host " this command to push the secrets automatically." -ForegroundColor DarkGray | ||
| } else { | ||
| Write-Host "Tip: re-run with -SetGitHubSecrets to push these via the GitHub CLI automatically." -ForegroundColor DarkGray | ||
| } | ||
| Write-Host "See https://maester.dev/docs/monitoring/github#add-entra-tenant-info-to-github-repos for details." -ForegroundColor Yellow | ||
| Write-Host "" | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.