feat: VSCode syntax highlighter#347
Conversation
…of functions and predicates
|
Caution Review failedFailed to post review comments 📝 WalkthroughWalkthroughAdds a VSCode syntax highlighting extension for Expressif: TextMate grammar and generation scripts, package manifest and VSIX packaging scripts, AppVeyor CI changes to produce VSIX artifacts, GitHub release asset upload/download helpers, and documentation updates. ChangesVSCode Syntax Highlighting Extension
🎯 3 (Moderate) | ⏱️ ~25 minutes
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
README.md (1)
12-18:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd the missing top navigation link usage.
Line 18 defines
[VSCode Syntax Highlighting Extension], but Line 12 never uses it, so the new section is not linked from the top nav and the reference stays unused.Suggested fix
-[About][] | [Quickstart][] | [Installing][] | [Functions and predicates][] +[About][] | [Quickstart][] | [Installing][] | [Functions and predicates][] | [VSCode Syntax Highlighting Extension][]🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@README.md` around lines 12 - 18, The top navigation list on line 12 is missing the newly defined link label [VSCode Syntax Highlighting Extension] from line 18; update the nav list (the pipe-separated links line containing [About] | [Quickstart] | [Installing] | [Functions and predicates]) to include [VSCode Syntax Highlighting Extension] so the reference is used and the new section is reachable from the top navigation.
🧹 Nitpick comments (6)
Expressif.Syntax/README (1)
36-42: ⚡ Quick winFormat installation steps as an ordered list for readability.
Lines 36-42 render as a compact text block in Markdown. Converting to a numbered list improves scannability for end users.
Suggested fix
-From VSIX -Open Visual Studio Code -Go to Extensions -Click ... (top-right) -Select Install from VSIX... -Choose your .vsix file -File Types +### From VSIX +1. Open Visual Studio Code. +2. Go to **Extensions**. +3. Click `...` (top-right). +4. Select **Install from VSIX...** +5. Choose your `.vsix` file. + +### File types🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Expressif.Syntax/README` around lines 36 - 42, The installation steps under the "From VSIX" section are written as a compact text block; convert them into a Markdown ordered list for readability by replacing the lines starting with "From VSIX", "Open Visual Studio Code", "Go to Extensions", "Click ... (top-right)", "Select Install from VSIX...", and "Choose your .vsix file" with a numbered list (1., 2., 3., ...) so the steps render as an ordered list in the README; keep the "File Types" heading after the list unchanged.Expressif.Syntax/New-tmLanguage.ps1 (1)
8-9: ⚡ Quick winRemove or wire
LanguageNameandScopeNameparameters.These parameters are currently unused, which makes the script contract misleading. Either remove them or include them in the model/template rendering path.
Proposed minimal cleanup
- [string] $LanguageName = "Expressif", - [string] $ScopeName = "source.expressif" + # Reserved for future template customization🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Expressif.Syntax/New-tmLanguage.ps1` around lines 8 - 9, The parameters LanguageName and ScopeName are declared but unused; either remove their declarations from New-tmLanguage.ps1 or wire them into the template rendering logic so they affect output; to fix, search for the [string] $LanguageName and [string] $ScopeName declarations and either delete them (and update any docs/tests expecting them) or pass those variables into whatever template/model rendering function you use (e.g., the function that builds the tmLanguage content or calls a template engine) so the generated file uses $LanguageName and $ScopeName in the appropriate fields.github.ps1 (2)
261-292: ⚡ Quick winFragile filename extraction using substring.
Line 290 extracts the filename from the URL using
Substring($url.LastIndexOf('/') + 1). This could fail if the URL structure is unexpected or doesn't contain a slash.♻️ Proposed fix using Split for robust parsing
- Invoke-WebRequest -Uri $url -OutFile $url.Substring($url.LastIndexOf('/') + 1) + $filename = $url.Split('/')[-1] + Invoke-WebRequest -Uri $url -OutFile $filename🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@github.ps1` around lines 261 - 292, The filename extraction in Download-Release-Asset uses $url.Substring($url.LastIndexOf('/') + 1) which is fragile; replace that logic with a robust extraction (e.g., create a [System.Uri] from $url then call [System.IO.Path]::GetFileName($uri.AbsolutePath) or split on '/' and take the last non-empty segment) and ensure you strip any query string or trailing slashes and fallback to a safe default filename if extraction yields empty; update the variable used in Invoke-WebRequest -OutFile accordingly (refer to Download-Release-Asset, $url and the Invoke-WebRequest -OutFile usage).
52-77: ⚡ Quick winContent-Type hardcoded as "application/zip" for all uploads.
Line 67 sets the Content-Type to "application/zip" for all file uploads. While VSIX files are ZIP-based, using "application/octet-stream" would be more accurate and flexible for handling different file types.
♻️ Proposed fix for flexible Content-Type
- $headers.Add("Content-Type", "application/zip") + $headers.Add("Content-Type", "application/octet-stream")🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@github.ps1` around lines 52 - 77, The Send-GitHub-FileUpload-Request function currently hardcodes the Content-Type to "application/zip"; change it to be flexible by using "application/octet-stream" as a safe default and do not overwrite an existing Content-Type header if one is supplied; update the header handling around $headers.Keys / $headers.Remove / $headers.Add so it first checks if $headers contains "Content-Type" and only adds "application/octet-stream" when absent (or alternatively accept a new parameter like [string] $ContentType and use that value if provided), and ensure $uri and Invoke-WebRequest usage stays the same.appveyor.yml (2)
110-115: ⚖️ Poor tradeoffHard-coded delay may mask an underlying timing issue.
The 5-second sleep before uploading release assets suggests a race condition or eventual consistency issue with GitHub's release API. While this may be necessary, consider whether a retry-with-backoff pattern would be more robust than a fixed delay.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@appveyor.yml` around lines 110 - 115, Replace the fixed Start-Sleep -Seconds 5 with a retry-with-backoff around the Upload-Release-Assets call: catch transient failures when calling the Upload-Release-Assets command (the block referencing Tag "v$($env:GitVersion_SemVer)" and Path "./.publish"), retry a configurable number of times with exponential backoff (and short jitter), log each attempt and failure, and fail only after exhausting retries so we don't mask the underlying timing/race condition with a hard-coded delay.
58-68: ⚡ Quick winConsider adding error handling for the info generation scripts.
The
generate-info.ps1scripts run without error checking. If either fails, the build continues to the tmBundle creation, which may produce incorrect results or fail unexpectedly.🛡️ Proposed fix to add error handling
- pwsh: | - & .\generate-info.ps1 function - & .\generate-info.ps1 predicate + & .\generate-info.ps1 function + if ($LASTEXITCODE -ne 0) { throw "Failed to generate function info" } + & .\generate-info.ps1 predicate + if ($LASTEXITCODE -ne 0) { throw "Failed to generate predicate info" }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@appveyor.yml` around lines 58 - 68, The generate-info.ps1 invocations run without error checking so failures can be ignored and downstream steps like New-tmBundle.ps1 will run against bad state; wrap each pwsh block that calls .\generate-info.ps1 (and the block that calls .\New-tmBundle.ps1) in explicit error handling: set ErrorActionPreference='Stop' or use -ErrorAction Stop when invoking generate-info.ps1, catch exceptions in a try/catch around the call, log the error and exit non‑zero (or rethrow) to halt the pipeline; do the same for the New-tmBundle.ps1 block (the Push-Location / Pop-Location block) so any failure there is propagated and the job stops.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@Expressif.Syntax/New-PackageJson.ps1`:
- Line 14: The Write-Host call prints "$($model.version)" but $model is still
JSON text, so it won't reliably show the actual version; change the logging to
read the version from a parsed JSON object (e.g., parse $model with
ConvertFrom-Json into a variable like $modelObj and use $modelObj.version, or
directly use (ConvertFrom-Json $model).version) and use that parsed value in the
Write-Host message to ensure the real version is printed.
In `@Expressif.Syntax/New-tmBundle.ps1`:
- Line 31: The success log uses an undefined variable $OutputFolder; locate the
variable that actually holds the generated VSIX path in this script (e.g., the
assignment for the package output such as $OutputPath, $PackageOutput or
$OutDir) and replace $OutputFolder in the Write-Host call (the line with
Write-Host "-> VSIX package generated in $OutputFolder") with that correct
variable so the printed path is accurate.
- Around line 89-91: The build currently downloads LICENSE via Copy-RemoteText
which couples the build to a remote branch; replace that remote fetch by copying
the repository's checked-in LICENSE into the build obj folder (e.g., use
Copy-Item or Add-Content to copy .\LICENSE -> .\obj\LICENSE) and guard with
Test-Path to fail fast if the file is missing; remove or comment out the
Copy-RemoteText call and update any references to rely on the local LICENSE so
packaging is deterministic for the checked-out commit.
In `@Expressif.Syntax/package.json.sbn`:
- Line 9: Replace the placeholder repository URL value in the package metadata
by updating the "url" field (in package.json.sbn) from
"https://github.com/your-org/expressif.git" to the actual Git repository URL for
this project (a valid https or git URL for the expressif repo), ensuring the
string is reachable and correct; also verify any other package metadata fields
that reference the repo (e.g., "repository" or "homepage") are updated to the
same real URL so marketplace metadata links are not broken.
---
Outside diff comments:
In `@README.md`:
- Around line 12-18: The top navigation list on line 12 is missing the newly
defined link label [VSCode Syntax Highlighting Extension] from line 18; update
the nav list (the pipe-separated links line containing [About] | [Quickstart] |
[Installing] | [Functions and predicates]) to include [VSCode Syntax
Highlighting Extension] so the reference is used and the new section is
reachable from the top navigation.
---
Nitpick comments:
In `@appveyor.yml`:
- Around line 110-115: Replace the fixed Start-Sleep -Seconds 5 with a
retry-with-backoff around the Upload-Release-Assets call: catch transient
failures when calling the Upload-Release-Assets command (the block referencing
Tag "v$($env:GitVersion_SemVer)" and Path "./.publish"), retry a configurable
number of times with exponential backoff (and short jitter), log each attempt
and failure, and fail only after exhausting retries so we don't mask the
underlying timing/race condition with a hard-coded delay.
- Around line 58-68: The generate-info.ps1 invocations run without error
checking so failures can be ignored and downstream steps like New-tmBundle.ps1
will run against bad state; wrap each pwsh block that calls .\generate-info.ps1
(and the block that calls .\New-tmBundle.ps1) in explicit error handling: set
ErrorActionPreference='Stop' or use -ErrorAction Stop when invoking
generate-info.ps1, catch exceptions in a try/catch around the call, log the
error and exit non‑zero (or rethrow) to halt the pipeline; do the same for the
New-tmBundle.ps1 block (the Push-Location / Pop-Location block) so any failure
there is propagated and the job stops.
In `@Expressif.Syntax/New-tmLanguage.ps1`:
- Around line 8-9: The parameters LanguageName and ScopeName are declared but
unused; either remove their declarations from New-tmLanguage.ps1 or wire them
into the template rendering logic so they affect output; to fix, search for the
[string] $LanguageName and [string] $ScopeName declarations and either delete
them (and update any docs/tests expecting them) or pass those variables into
whatever template/model rendering function you use (e.g., the function that
builds the tmLanguage content or calls a template engine) so the generated file
uses $LanguageName and $ScopeName in the appropriate fields.
In `@Expressif.Syntax/README`:
- Around line 36-42: The installation steps under the "From VSIX" section are
written as a compact text block; convert them into a Markdown ordered list for
readability by replacing the lines starting with "From VSIX", "Open Visual
Studio Code", "Go to Extensions", "Click ... (top-right)", "Select Install from
VSIX...", and "Choose your .vsix file" with a numbered list (1., 2., 3., ...) so
the steps render as an ordered list in the README; keep the "File Types" heading
after the list unchanged.
In `@github.ps1`:
- Around line 261-292: The filename extraction in Download-Release-Asset uses
$url.Substring($url.LastIndexOf('/') + 1) which is fragile; replace that logic
with a robust extraction (e.g., create a [System.Uri] from $url then call
[System.IO.Path]::GetFileName($uri.AbsolutePath) or split on '/' and take the
last non-empty segment) and ensure you strip any query string or trailing
slashes and fallback to a safe default filename if extraction yields empty;
update the variable used in Invoke-WebRequest -OutFile accordingly (refer to
Download-Release-Asset, $url and the Invoke-WebRequest -OutFile usage).
- Around line 52-77: The Send-GitHub-FileUpload-Request function currently
hardcodes the Content-Type to "application/zip"; change it to be flexible by
using "application/octet-stream" as a safe default and do not overwrite an
existing Content-Type header if one is supplied; update the header handling
around $headers.Keys / $headers.Remove / $headers.Add so it first checks if
$headers contains "Content-Type" and only adds "application/octet-stream" when
absent (or alternatively accept a new parameter like [string] $ContentType and
use that value if provided), and ensure $uri and Invoke-WebRequest usage stays
the same.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 24f7e568-0c05-4749-8b78-8ac4e5b52ef7
📒 Files selected for processing (15)
.config/dotnet-tools.jsonExpressif.Syntax/Ensure-DotnetLocalToolInstalled.ps1Expressif.Syntax/Expressif.tmLanguage.json.sbnExpressif.Syntax/New-PackageJson.ps1Expressif.Syntax/New-tmBundle.ps1Expressif.Syntax/New-tmLanguage.ps1Expressif.Syntax/READMEExpressif.Syntax/language-configuration.jsonExpressif.Syntax/package.json.sbnExpressif.slnREADME.mdappveyor.ymldocs/_data/navigation_docs.ymldocs/_docs/vscode-extension-syntax.mdgithub.ps1
|
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
Expressif.Syntax/New-tmBundle.ps1 (1)
89-91:⚠️ Potential issue | 🟠 Major | ⚡ Quick winCopy LICENSE from repository instead of downloading from remote.
Downloading the LICENSE from the remote
mainbranch introduces non-determinism and a network dependency. The build should be reproducible for any checked-out commit and should not depend on the current state of the remote branch.🔧 Proposed fix
Write-Host "== Copy license ==" -Copy-RemoteText ` - -Url "https://raw.githubusercontent.com/Seddryck/Expressif/main/LICENSE" ` - -OutputPath ".\obj\LICENSE" +$licensePath = Join-Path $PSScriptRoot "..\LICENSE" +if (-not (Test-Path $licensePath)) { + throw "LICENSE file not found at $licensePath" +} +Copy-Item $licensePath .\obj\LICENSE🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Expressif.Syntax/New-tmBundle.ps1` around lines 89 - 91, Replace the network download call to Copy-RemoteText in New-tmBundle.ps1 with a local file copy: instead of calling Copy-RemoteText -Url "https://.../LICENSE" -OutputPath ".\obj\LICENSE", copy the repository LICENSE file into .\obj\LICENSE (use a path based on $PSScriptRoot or the script's location to locate the repo root), ensure the .\obj directory exists (create it if necessary), and remove any network dependency so the build uses the checked-in LICENSE file.
🧹 Nitpick comments (2)
Expressif.Syntax/New-tmLanguage.ps1 (2)
34-39: ⚡ Quick winConsider validating output directory exists.
The output path may reference a directory that doesn't exist yet. While the calling script (
New-tmBundle.ps1) creates it, adding a check here would make the script more robust for standalone use.🛡️ Proposed validation
+$outputDir = Split-Path $OutputPath -Parent +if ($outputDir -and -not (Test-Path $outputDir)) { + New-Item -ItemType Directory -Path $outputDir -Force | Out-Null +} + Write-Host "Running Didot via local installation..." $model | dotnet tool run didot `🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Expressif.Syntax/New-tmLanguage.ps1` around lines 34 - 39, The script invokes "dotnet tool run didot ... -o $OutputPath" without ensuring the output directory exists; update New-tmLanguage.ps1 to validate and create the directory referenced by $OutputPath (use Test-Path and New-Item -ItemType Directory or equivalent) before calling "dotnet tool run didot" so the tool has a valid output location.
10-11: ⚡ Quick winConsider validating input files exist.
The script reads
function.jsonandpredicate.jsonwithout checking if they exist. Adding validation would provide clearer error messages if the files are missing.🛡️ Proposed validation
+$functionPath = Join-Path $InputFolder "function.json" +$predicatePath = Join-Path $InputFolder "predicate.json" + +if (-not (Test-Path $functionPath)) { + throw "function.json not found in $InputFolder" +} +if (-not (Test-Path $predicatePath)) { + throw "predicate.json not found in $InputFolder" +} + $model = [ordered]@{ - functions = Get-Content $InputFolder\function.json -Raw | + functions = Get-Content $functionPath -Raw | ConvertFrom-Json | Where-Object { $_.IsPublic -eq $true } | ForEach-Object { [ordered]@{ name = $_.Name scope = $_.Scope regex = [regex]::Escape($_.Name) } } - predicates = Get-Content $InputFolder\predicate.json -Raw | + predicates = Get-Content $predicatePath -Raw |Also applies to: 20-21
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Expressif.Syntax/New-tmLanguage.ps1` around lines 10 - 11, Add existence checks for the input JSON files before trying to read them: for the block that sets the "functions" variable (where Get-Content $InputFolder\function.json | ConvertFrom-Json is used) and the similar block that reads "predicate.json" (used to build predicates), call Test-Path on each full file path and if the file is missing emit a clear terminating error (e.g., throw or Write-Error -ErrorAction Stop) that includes the missing filename and $InputFolder so the script fails fast with a readable message; update the code paths around the "functions" and "predicates" reads to perform this validation and only call Get-Content/ConvertFrom-Json after the file is confirmed to exist.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@github.ps1`:
- Around line 289-291: Remove the stray diff artifact by deleting the leading
plus character before the Invoke-WebRequest call inside the
Download-Release-Asset function; ensure the line reads Invoke-WebRequest -Uri
$url -OutFile $filename (no leading '+' or other extraneous characters) so the
github.ps1 script parses and the Download-Release-Asset function runs correctly.
- Around line 153-159: The code calls Send-GitHub-Get-Request with Segments
@('releases') and then filters by tag, which hits the paginated /releases list
and misses older tags; change the request to use the tag-specific endpoint
instead: call Send-GitHub-Get-Request with Segments @('releases','tags',$tag)
(or equivalent to GET /releases/tags/{tag}), parse the response Content with
ConvertFrom-Json and return that object directly (remove the
Select-Object/Where-Object filtering). Update the code around the
Send-GitHub-Get-Request invocation in Get-Release-Info so it returns the single
release JSON for the given $tag.
---
Duplicate comments:
In `@Expressif.Syntax/New-tmBundle.ps1`:
- Around line 89-91: Replace the network download call to Copy-RemoteText in
New-tmBundle.ps1 with a local file copy: instead of calling Copy-RemoteText -Url
"https://.../LICENSE" -OutputPath ".\obj\LICENSE", copy the repository LICENSE
file into .\obj\LICENSE (use a path based on $PSScriptRoot or the script's
location to locate the repo root), ensure the .\obj directory exists (create it
if necessary), and remove any network dependency so the build uses the
checked-in LICENSE file.
---
Nitpick comments:
In `@Expressif.Syntax/New-tmLanguage.ps1`:
- Around line 34-39: The script invokes "dotnet tool run didot ... -o
$OutputPath" without ensuring the output directory exists; update
New-tmLanguage.ps1 to validate and create the directory referenced by
$OutputPath (use Test-Path and New-Item -ItemType Directory or equivalent)
before calling "dotnet tool run didot" so the tool has a valid output location.
- Around line 10-11: Add existence checks for the input JSON files before trying
to read them: for the block that sets the "functions" variable (where
Get-Content $InputFolder\function.json | ConvertFrom-Json is used) and the
similar block that reads "predicate.json" (used to build predicates), call
Test-Path on each full file path and if the file is missing emit a clear
terminating error (e.g., throw or Write-Error -ErrorAction Stop) that includes
the missing filename and $InputFolder so the script fails fast with a readable
message; update the code paths around the "functions" and "predicates" reads to
perform this validation and only call Get-Content/ConvertFrom-Json after the
file is confirmed to exist.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 9a8ab59a-58b7-41a1-9ba3-a9e4fdbb03df
📒 Files selected for processing (7)
Expressif.Syntax/Ensure-DotnetLocalToolInstalled.ps1Expressif.Syntax/New-PackageJson.ps1Expressif.Syntax/New-tmBundle.ps1Expressif.Syntax/New-tmLanguage.ps1Expressif.Syntax/READMEExpressif.Syntax/package.json.sbngithub.ps1
✅ Files skipped from review due to trivial changes (1)
- Expressif.Syntax/README
🚧 Files skipped from review as they are similar to previous changes (3)
- Expressif.Syntax/package.json.sbn
- Expressif.Syntax/Ensure-DotnetLocalToolInstalled.ps1
- Expressif.Syntax/New-PackageJson.ps1
| $response = Send-GitHub-Get-Request ` | ||
| -Owner $context.Owner ` | ||
| -Repository $context.Repository ` | ||
| -Segments @('releases') ` | ||
| -Headers $($context.SecretToken | Get-GitHub-Headers) | ||
| $json = $response | Select-Object -ExpandProperty Content | ConvertFrom-Json | ||
| return $json | Where-Object {$_.tag_name -eq $tag} |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
GitHub REST API: what are the default pagination rules for GET /repos/{owner}/{repo}/releases, and is there a dedicated GET /repos/{owner}/{repo}/releases/tags/{tag} endpoint?
💡 Result:
Default pagination rules for GET /repos/{owner}/{repo}/releases (GitHub REST API): 1) Query parameters: you can paginate using page and per_page. The endpoint supports per_page (max 100) and page; per_page defaults to 30 and page defaults to 1.[1] 2) Pagination navigation: when results are paginated, GitHub includes a link header in the response that points to the next/last pages; you should follow those URLs to retrieve additional pages.[2][3] Dedicated endpoint for a release by tag: yes. There is a dedicated GET endpoint to fetch a single published release by its tag name: GET /repos/{owner}/{repo}/releases/tags/{tag}. It returns the “published release with the specified tag”.[1]
Citations:
- 1: https://docs.github.com/rest/releases/releases
- 2: https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api
- 3: https://docs.github.com/en/rest/using-the-rest-api/using-pagination-in-the-rest-api?apiVersion=2026-03-10
🏁 Script executed:
# First, find the github.ps1 file
fd -t f "github.ps1"Repository: Seddryck/Expressif
Length of output: 73
🏁 Script executed:
# Read the github.ps1 file to examine the relevant sections
wc -l github.ps1Repository: Seddryck/Expressif
Length of output: 77
🏁 Script executed:
# Examine lines 153-159 (the function in question)
sed -n '153,159p' github.ps1Repository: Seddryck/Expressif
Length of output: 395
🏁 Script executed:
# Examine the area around line 291 for the parse error mentioned in the scratchpad
sed -n '280,300p' github.ps1Repository: Seddryck/Expressif
Length of output: 824
🏁 Script executed:
# Get more context around lines 153-159 to identify the function
sed -n '145,165p' github.ps1Repository: Seddryck/Expressif
Length of output: 752
🏁 Script executed:
# Verify the exact nature of the parse error by checking the syntax
# Look at the broader context around line 291
sed -n '285,305p' github.ps1Repository: Seddryck/Expressif
Length of output: 759
🏁 Script executed:
# Check the complete Download-Release-Asset function to verify syntax validity
sed -n '268,310p' github.ps1Repository: Seddryck/Expressif
Length of output: 1470
🏁 Script executed:
# Verify there are no actual PowerShell syntax errors by checking the function is properly closed
sed -n '268,330p' github.ps1 | cat -nRepository: Seddryck/Expressif
Length of output: 2453
🏁 Script executed:
# Check the exact bytes around line 291 to confirm if the leading + is actually in the file
sed -n '291p' github.ps1 | od -c | head -20Repository: Seddryck/Expressif
Length of output: 103
🏁 Script executed:
# Also verify the function structure to ensure Download-Release-Asset is correctly defined
sed -n '250,295p' github.ps1 | cat -nRepository: Seddryck/Expressif
Length of output: 1905
Use the tag-specific release endpoint to avoid pagination limits.
GET /releases defaults to 30 items per page, so repositories with more than 30 releases will fail to find older tags. This breaks asset operations for those tags since Upload-Release-Assets and List-Release-Assets depend on Get-Release-Info. Use the dedicated tag-specific endpoint instead.
Suggested fix
$response = Send-GitHub-Get-Request `
-Owner $context.Owner `
-Repository $context.Repository `
- -Segments @('releases') `
+ -Segments @('releases', 'tags', $tag) `
-Headers $($context.SecretToken | Get-GitHub-Headers)
- $json = $response | Select-Object -ExpandProperty Content | ConvertFrom-Json
- return $json | Where-Object {$_.tag_name -eq $tag}
+ return $response | Select-Object -ExpandProperty Content | ConvertFrom-Json📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| $response = Send-GitHub-Get-Request ` | |
| -Owner $context.Owner ` | |
| -Repository $context.Repository ` | |
| -Segments @('releases') ` | |
| -Headers $($context.SecretToken | Get-GitHub-Headers) | |
| $json = $response | Select-Object -ExpandProperty Content | ConvertFrom-Json | |
| return $json | Where-Object {$_.tag_name -eq $tag} | |
| $response = Send-GitHub-Get-Request ` | |
| -Owner $context.Owner ` | |
| -Repository $context.Repository ` | |
| -Segments @('releases', 'tags', $tag) ` | |
| -Headers $($context.SecretToken | Get-GitHub-Headers) | |
| return $response | Select-Object -ExpandProperty Content | ConvertFrom-Json |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@github.ps1` around lines 153 - 159, The code calls Send-GitHub-Get-Request
with Segments @('releases') and then filters by tag, which hits the paginated
/releases list and misses older tags; change the request to use the tag-specific
endpoint instead: call Send-GitHub-Get-Request with Segments
@('releases','tags',$tag) (or equivalent to GET /releases/tags/{tag}), parse the
response Content with ConvertFrom-Json and return that object directly (remove
the Select-Object/Where-Object filtering). Update the code around the
Send-GitHub-Get-Request invocation in Get-Release-Info so it returns the single
release JSON for the given $tag.
| Write-Host "Downloading $($asset.name) from $url ..." | ||
| $filename = $url.Split('/')[-1] | ||
| + Invoke-WebRequest -Uri $url -OutFile $filename |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
sed -n '289,291p' github.ps1
rg -n '^\+' github.ps1Repository: Seddryck/Expressif
Length of output: 255
🏁 Script executed:
# Get the function context around line 291
sed -n '280,300p' github.ps1
# Check if there are any other lines with unusual leading characters
rg -n '^\s*[\+\-]' github.ps1 | head -20
# Find the Download-Release-Asset function definition
rg -n 'function.*Download-Release-Asset' github.ps1 -A 5Repository: Seddryck/Expressif
Length of output: 1875
Remove the stray + before Invoke-WebRequest.
The literal + at line 291 is a diff artifact that causes github.ps1 to fail parsing, preventing the Download-Release-Asset function from running.
Suggested fix
-+ Invoke-WebRequest -Uri $url -OutFile $filename
+ Invoke-WebRequest -Uri $url -OutFile $filename📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Write-Host "Downloading $($asset.name) from $url ..." | |
| $filename = $url.Split('/')[-1] | |
| + Invoke-WebRequest -Uri $url -OutFile $filename | |
| Write-Host "Downloading $($asset.name) from $url ..." | |
| $filename = $url.Split('/')[-1] | |
| Invoke-WebRequest -Uri $url -OutFile $filename |
🧰 Tools
🪛 PSScriptAnalyzer (1.25.0)
[error] 291-291: Missing expression after unary operator '+'.
(MissingExpressionAfterOperator)
[error] 291-291: Unexpected token 'Invoke-WebRequest' in expression or statement.
(UnexpectedToken)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@github.ps1` around lines 289 - 291, Remove the stray diff artifact by
deleting the leading plus character before the Invoke-WebRequest call inside the
Download-Release-Asset function; ensure the line reads Invoke-WebRequest -Uri
$url -OutFile $filename (no leading '+' or other extraneous characters) so the
github.ps1 script parses and the Download-Release-Asset function runs correctly.
feat: syntax highlighter for Expressif



Summary by CodeRabbit
New Features
Documentation
Chores