Conversation
# SmartHopper 1.4.2-alpha: macOS Compatibility Verified [Patch] This patch release delivers verified macOS compatibility for provider hash verification and fixes a GhJSON validation error in script tools. This is the first macOS-compatible release available through Yak/Rhino package manager. ## Detailed list of changes: - Fixed missing `Id` property validation error in `script_generate` and `script_edit` tools when `InstanceGuid` is null - Fixed macOS compatibility issue with provider hash verification system ([#263](#263)) - Successfully verified macOS provider hash verification - first macOS-compatible release through Yak/Rhino package manager - Special thanks to [nofcfy-fanqi](https://github.com/nofcfy-fanqi) for macOS testing!
chore: add provider hash manifest for version 1.4.2-alpha (dual platform) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
…release stages manager (#412)
|
🏷️ This PR has been automatically assigned to milestone 1.4.2-alpha based on the version in |
There was a problem hiding this comment.
Pull request overview
This PR updates the release-promotion automation to use a richer “promotion eligibility” decision (beyond just open issues), and documents the updated promotion criteria. It also adds a new build-hash manifest for 1.4.2-alpha.
Changes:
- Enhance promotion decision logging and summary output in
release-promotion.yml. - Expand
check-issues-for-versioncomposite action to output release-age and last-closed-issue-age signals and acan-promotedecision. - Update release workflow documentation to reflect the new promotion rules; add
hashes/1.4.2-alpha.json.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
hashes/1.4.2-alpha.json |
Adds SHA-256 hashes + metadata for the 1.4.2-alpha provider artifacts. |
.github/workflows/release-promotion.yml |
Updates promotion decision logging and produces a richer markdown summary for validations/decision. |
.github/workflows/RELEASE_WORKFLOW.md |
Documents the updated promotion gating conditions and blocking scenarios. |
.github/actions/versioning/check-issues-for-version/action.yml |
Adds promotion-eligibility checks/outputs (release age, last closed issue age, aggregate can-promote). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Search for all open issues with labels matching the base version (any stage) | ||
| # This will match: version: X.Y.Z, version: X.Y.Z-alpha, version: X.Y.Z-beta, etc. | ||
| $openIssues = @() | ||
| $page = 1 | ||
| $perPage = 100 | ||
|
|
||
| do { | ||
| # Search API query: state:open label:"version: X.Y.Z" created:>=YYYY-MM-DD | ||
| $query = "state:open label:""$labelName"" created:>=$cutoffDate repo:$repo" | ||
| # Search for issues with labels starting with "version: X.Y.Z" | ||
| $query = "state:open label:""version: $baseVersion"" repo:$repo" | ||
| $uri = "https://api.github.com/search/issues?q=$([Uri]::EscapeDataString($query))&per_page=$perPage&page=$page" |
There was a problem hiding this comment.
The open-issue search query uses label:"version: $baseVersion", but GitHub search label matching is exact—this will not match stage labels like version: 1.4.3-alpha / version: 1.4.3-beta as the comment claims. If you want “all stages”, you’ll need to explicitly query each expected label (e.g., base + alpha/beta/rc) or first discover matching labels via the Labels API and then query issues for each label.
| Write-Warning "Failed to fetch release: $($_.Exception.Message)" | ||
| echo "release_date=unknown" >> $env:GITHUB_OUTPUT | ||
| echo "release_age_days=-1" >> $env:GITHUB_OUTPUT | ||
| echo "release_old_enough=unknown" >> $env:GITHUB_OUTPUT |
There was a problem hiding this comment.
On release-fetch failure, the code sets release_old_enough=unknown but does not set $canPromote = $false or add a blocking reason. This can incorrectly allow promotion when the release tag doesn’t exist or the API call fails. Consider treating this as a blocking condition (e.g., release_check_failed) and setting $canPromote = $false in the catch.
| echo "release_old_enough=unknown" >> $env:GITHUB_OUTPUT | |
| echo "release_old_enough=unknown" >> $env:GITHUB_OUTPUT | |
| $canPromote = $false | |
| $blockingReasons += "release_check_failed" |
| Write-Warning "Failed to check closed issues: $($_.Exception.Message)" | ||
| echo "last_closed_issue_date=unknown" >> $env:GITHUB_OUTPUT | ||
| echo "last_closed_age_days=-1" >> $env:GITHUB_OUTPUT | ||
| echo "last_closed_old_enough=unknown" >> $env:GITHUB_OUTPUT |
There was a problem hiding this comment.
Similarly, if the closed-issues check fails, the action sets last_closed_old_enough=unknown but doesn’t block promotion. That can allow promotion even when eligibility couldn’t be validated. Recommend setting $canPromote = $false and adding a blocking reason (e.g., closed_issue_check_failed) in the catch.
| echo "last_closed_old_enough=unknown" >> $env:GITHUB_OUTPUT | |
| echo "last_closed_old_enough=unknown" >> $env:GITHUB_OUTPUT | |
| # Block promotion if closed-issue eligibility could not be validated | |
| if (-not $blockingReasons) { | |
| $blockingReasons = @() | |
| } | |
| $reason = "closed_issue_check_failed" | |
| $blockingReasons += $reason | |
| $canPromote = $false |
| # Search for closed issues with version label, sorted by closed date (most recent first) | ||
| $query = "state:closed label:""$labelName"" repo:$repo" | ||
| $closedIssuesUri = "https://api.github.com/search/issues?q=$([Uri]::EscapeDataString($query))&sort=updated&order=desc&per_page=1" | ||
| $closedResponse = Invoke-RestMethod -Uri $closedIssuesUri -Headers $headers -Method GET | ||
|
|
||
| if ($closedResponse.total_count -gt 0 -and $closedResponse.items.Count -gt 0) { | ||
| $lastClosedIssue = $closedResponse.items[0] |
There was a problem hiding this comment.
The comment says the search is “sorted by closed date”, but the query uses sort=updated. An older closed issue that was edited/commented recently can appear first, causing an incorrect last_closed_age_days. To make this accurate, fetch a larger set of closed issues and compute the max closed_at yourself (or use a different endpoint/strategy that avoids relying on updated).
| # Search for closed issues with version label, sorted by closed date (most recent first) | |
| $query = "state:closed label:""$labelName"" repo:$repo" | |
| $closedIssuesUri = "https://api.github.com/search/issues?q=$([Uri]::EscapeDataString($query))&sort=updated&order=desc&per_page=1" | |
| $closedResponse = Invoke-RestMethod -Uri $closedIssuesUri -Headers $headers -Method GET | |
| if ($closedResponse.total_count -gt 0 -and $closedResponse.items.Count -gt 0) { | |
| $lastClosedIssue = $closedResponse.items[0] | |
| # Fetch recent closed issues with version label and compute most recent closed date | |
| $query = "state:closed label:""$labelName"" repo:$repo" | |
| $closedIssuesUri = "https://api.github.com/search/issues?q=$([Uri]::EscapeDataString($query))&sort=updated&order=desc&per_page=100" | |
| $closedResponse = Invoke-RestMethod -Uri $closedIssuesUri -Headers $headers -Method GET | |
| if ($closedResponse.total_count -gt 0 -and $closedResponse.items.Count -gt 0) { | |
| $lastClosedIssue = $closedResponse.items | Sort-Object {[DateTime]::Parse($_.closed_at)} -Descending | Select-Object -First 1 |
| @@ -1,5 +1,5 @@ | |||
| name: 'Check Issues for Version' | |||
| description: 'Check if any open issues exist with a specific version label within a time period' | |||
| description: 'Check promotion eligibility: milestone status, release age, and open issues with version label (all stages)' | |||
There was a problem hiding this comment.
The action description claims it checks “milestone status”, but the implementation no longer checks milestones (and no milestone-related outputs are produced). Please update the description to match the current behavior or reintroduce milestone checking/outputs if they’re still required.
| Write-Host "=== Promotion Decision for $version ===" | ||
| Write-Host "" | ||
| Write-Host "Validation Results:" | ||
| Write-Host " • Milestone open issues: ${{ steps.check-issues.outputs.milestone-open-count }}" |
There was a problem hiding this comment.
This step prints steps.check-issues.outputs.milestone-open-count, but check-issues-for-version doesn’t define or set a milestone-open-count output anymore. This will always be blank and is misleading in logs; either remove this line or add the corresponding output back to the action.
| Write-Host " • Milestone open issues: ${{ steps.check-issues.outputs.milestone-open-count }}" |
| 2. If no open issues for 30 days → promotes to next stage | ||
| 3. Creates promotion PR (e.g., `1.4.3-alpha` → `1.4.3-beta`) | ||
| 2. **Promotion requires ALL three conditions**: | ||
| - ✅ **No open issues with version label** (any stage of base version, e.g., `version: 1.4.3-alpha`) |
There was a problem hiding this comment.
The doc states promotion blocks on “any open issue labeled version: 1.4.3 or version: 1.4.3-alpha (any stage)”, but the current action implementation only searches for the exact base label version: X.Y.Z (it won’t match version: X.Y.Z-alpha/beta/rc). Either adjust the doc to the actual behavior or update the action to truly check all stages.
| - ✅ **No open issues with version label** (any stage of base version, e.g., `version: 1.4.3-alpha`) | |
| - ✅ **No open issues with base version label** (e.g., `version: 1.4.3`; stage-specific labels like `version: 1.4.3-alpha/beta/rc` are not checked) |
No description provided.