diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 9ef6c2af7..b05586197 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -1,7 +1,12 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
version: 2
updates:
# Enable version updates for GitHub Actions
- - package-ecosystem: "github-actions"
+ - package-ecosystem: "github-actions" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 37f533274..21820dabf 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -7,11 +7,11 @@ name: Build Cmder
# Controls when the action will run. Triggers the workflow on push or pull request events but only for the main branch
on:
push:
- branches: [ "master" ]
+ branches: [ "master", "main" ]
tags:
- "v*"
pull_request:
- branches: [ "master", "development" ]
+ branches: [ "master", "main", "development" ]
#---------------------------------#
# environment configuration #
@@ -42,34 +42,116 @@ jobs:
- name: Summary - Repository checkout
shell: pwsh
run: |
- echo "## ๐ฆ Build Cmder - Workflow Summary" >> $env:GITHUB_STEP_SUMMARY
- echo "" >> $env:GITHUB_STEP_SUMMARY
- echo "### Repository Information" >> $env:GITHUB_STEP_SUMMARY
- echo "| Property | Value |" >> $env:GITHUB_STEP_SUMMARY
- echo "| --- | --- |" >> $env:GITHUB_STEP_SUMMARY
- echo "| Repository | \`${{ github.repository }}\` |" >> $env:GITHUB_STEP_SUMMARY
- echo "| Branch | \`${{ github.ref_name }}\` |" >> $env:GITHUB_STEP_SUMMARY
- echo "| Commit | \`${{ github.sha }}\` |" >> $env:GITHUB_STEP_SUMMARY
- echo "| Actor | @${{ github.actor }} |" >> $env:GITHUB_STEP_SUMMARY
- echo "| Workflow | \`${{ github.workflow }}\` |" >> $env:GITHUB_STEP_SUMMARY
- echo "" >> $env:GITHUB_STEP_SUMMARY
+ # Get Cmder version
+ . scripts/utils.ps1
+ $cmderVersion = Get-VersionStr
+ $buildTime = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
+
+ # Determine branch and PR information
+ $refName = "${{ github.ref_name }}"
+ $headRef = "${{ github.head_ref }}"
+ $eventName = "${{ github.event_name }}"
+ $prNumber = $null
+ $actualBranchName = $refName
+ $branchLink = ""
+ $prLink = ""
+
+ # Check if this is a PR merge ref (e.g., "3061/merge")
+ if ($refName -match '^(\d+)/(merge|head)$') {
+ $prNumber = $Matches[1]
+ # Use head_ref for the actual branch name if available
+ if ($headRef) {
+ $actualBranchName = $headRef
+ }
+ $branchLink = "https://github.com/${{ github.repository }}/tree/$actualBranchName"
+ $prLink = "https://github.com/${{ github.repository }}/pull/$prNumber"
+ } elseif ($eventName -eq "pull_request") {
+ # This is a pull request event
+ $prNumber = "${{ github.event.pull_request.number }}"
+ if ($headRef) {
+ $actualBranchName = $headRef
+ }
+ $branchLink = "https://github.com/${{ github.repository }}/tree/$actualBranchName"
+ $prLink = "https://github.com/${{ github.repository }}/pull/$prNumber"
+ } else {
+ # Regular branch, link to the branch tree
+ $branchLink = "https://github.com/${{ github.repository }}/tree/$refName"
+ }
+
+ $summary = @"
+ ## ๐ฆ Build Cmder - Workflow Summary
+
+ Build started: ``$buildTime``
+
+ ### Repository Information
+ | Property | Value |
+ | --- | --- |
+ | Repository | [``${{ github.repository }}``](https://github.com/${{ github.repository }}) |
+ | Branch | [``$actualBranchName``]($branchLink) |
+ $(if ($prNumber) { "| Pull Request | [#$prNumber]($prLink) |" })
+ | Commit | [``${{ github.sha }}``](https://github.com/${{ github.repository }}/commit/${{ github.sha }}) |
+ | Actor | [@${{ github.actor }}](https://github.com/${{ github.actor }}) |
+ | Workflow | ``${{ github.workflow }}`` |
+ | Cmder Version | **$cmderVersion** |
+
+ ---
+
+ ### ๐๏ธ Vendor Packages ([sources.json](vendor/sources.json))
+ | Package | Version |
+ | --- | --- |
+ "@
+
+ # Read vendor sources.json and add to summary
+ $vendorSources = Get-Content -Raw "vendor/sources.json" | ConvertFrom-Json
+ if ($vendorSources.Count -eq 0) {
+ $summary += "`n| _No vendor packages found_ | |"
+ } else {
+ foreach ($vendor in $vendorSources) {
+ # Create release link based on vendor package
+ $versionLink = "$($vendor.version)"
+ if ($vendor.url) {
+ # Extract owner/repo/tag from the URL and create release link
+ # Handle both /releases/download/ and /archive/ URLs
+ if ($vendor.url -match 'github\.com/([^/]+)/([^/]+)/(releases/download|archive)/([^/]+)') {
+ $owner = $Matches[1]
+ $repo = $Matches[2]
+ $pathType = $Matches[3]
+ $tag = $Matches[4]
+ if ($pathType -eq 'archive') {
+ $tag = $tag -replace '\.(?:tar\.gz|tgz|zip)$', ''
+ }
+ $versionLink = "[$($vendor.version)](https://github.com/$owner/$repo/releases/tag/$tag)"
+ }
+ }
+ $summary += "`n| ``$($vendor.name)`` | $versionLink |"
+ }
+ }
+
+ $summary += "`n"
+
+ $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8
- name: Add MSBuild to PATH
- uses: microsoft/setup-msbuild@v2
+ uses: microsoft/setup-msbuild@v3
- name: Build Cmder Launcher
shell: pwsh
working-directory: scripts
- run: .\build.ps1 -Compile -verbose -terminal all
+ run: .\build.ps1 -Compile -verbose -terminal -all -installPacman
- name: Summary - Build completed
if: success()
shell: pwsh
run: |
- echo "### โ
Build Status" >> $env:GITHUB_STEP_SUMMARY
- echo "" >> $env:GITHUB_STEP_SUMMARY
- echo "Cmder launcher successfully compiled." >> $env:GITHUB_STEP_SUMMARY
- echo "" >> $env:GITHUB_STEP_SUMMARY
+ $summary = @"
+
+ ---
+
+ โ
Cmder built successfully.
+
+ "@
+
+ $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8
- name: Pack the built files
shell: pwsh
@@ -116,66 +198,90 @@ jobs:
path: build/cmder_wt_mini.zip
name: cmder_wt_mini.zip
- - name: Summary - Package artifacts
- if: success()
- shell: pwsh
- run: |
- echo "### ๐ฆ Artifacts Created" >> $env:GITHUB_STEP_SUMMARY
- echo "" >> $env:GITHUB_STEP_SUMMARY
- echo "| Artifact | Size | Hash (SHA256) |" >> $env:GITHUB_STEP_SUMMARY
- echo "| --- | --- | --- |" >> $env:GITHUB_STEP_SUMMARY
- $artifacts = @("cmder.zip", "cmder.7z", "cmder_mini.zip")
- foreach ($artifact in $artifacts) {
- $path = "build/$artifact"
- if (Test-Path $path) {
- $size = (Get-Item $path).Length / 1MB
- # Truncate hash to first 16 chars for summary readability (full hash in hashes.txt)
- $hash = (Get-FileHash $path -Algorithm SHA256).Hash.Substring(0, 16)
- echo "| \`$artifact\` | $([math]::Round($size, 2)) MB | \`$hash...\` |" >> $env:GITHUB_STEP_SUMMARY
- }
- }
- echo "" >> $env:GITHUB_STEP_SUMMARY
-
- name: Upload artifact (cmder.zip)
- uses: actions/upload-artifact@v6
+ uses: actions/upload-artifact@v7
with:
path: build/cmder.zip
name: cmder.zip
+ archive: false
if-no-files-found: error
- name: Upload artifact (cmder.7z)
- uses: actions/upload-artifact@v6
+ uses: actions/upload-artifact@v7
with:
path: build/cmder.7z
name: cmder.7z
+ archive: false
- name: Upload artifact (cmder_mini.zip)
- uses: actions/upload-artifact@v6
+ uses: actions/upload-artifact@v7
with:
path: build/cmder_mini.zip
name: cmder_mini.zip
+ archive: false
- name: Upload artifact (hashes.txt)
- uses: actions/upload-artifact@v6
+ uses: actions/upload-artifact@v7
with:
path: build/hashes.txt
name: hashes.txt
+ archive: false
- name: Summary - Artifacts uploaded
if: success()
shell: pwsh
+ env:
+ GH_TOKEN: ${{ github.token }}
run: |
- echo "### โ๏ธ Upload Status" >> $env:GITHUB_STEP_SUMMARY
- echo "" >> $env:GITHUB_STEP_SUMMARY
- echo "All artifacts successfully uploaded to GitHub Actions:" >> $env:GITHUB_STEP_SUMMARY
- echo '- โ
`cmder.zip`' >> $env:GITHUB_STEP_SUMMARY
- echo '- โ
`cmder.7z`' >> $env:GITHUB_STEP_SUMMARY
- echo '- โ
`cmder_mini.zip`' >> $env:GITHUB_STEP_SUMMARY
- echo '- โ
`hashes.txt`' >> $env:GITHUB_STEP_SUMMARY
- echo "" >> $env:GITHUB_STEP_SUMMARY
+ # Source utility functions
+ . scripts/utils.ps1
+
+ $summary = @"
+
+ ### ๐๏ธ Artifacts
+
+ | Artifact | Size | Hash (SHA256) |
+ | --- | --- | --- |
+ "@
+
+ # Get all files from the build directory (excluding directories and hidden files)
+ if (Test-Path "build") {
+ $buildFiles = Get-ChildItem -Path "build" -File | Where-Object { -not $_.Name.StartsWith('.') } | Sort-Object Name
+
+ foreach ($file in $buildFiles) {
+ $artifact = $file.Name
+ $path = $file.FullName
+ $sizeFormatted = Format-FileSize -Bytes $file.Length
+ $hash = (Get-FileHash $path -Algorithm SHA256).Hash
+
+ # Try to get the actual artifact download URL
+ $downloadUrl = Get-ArtifactDownloadUrl -ArtifactName $artifact -Repository "${{ github.repository }}" -RunId "${{ github.run_id }}"
+ $warning = ""
+
+ if (-not $downloadUrl) {
+ # Fallback to workflow run page if artifact URL fetch fails
+ $downloadUrl = "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
+ $warning = " โ ๏ธ"
+ }
+
+ # Determine emoji based on file type
+ if ($artifact -match '\.txt$') {
+ $emoji = "๐"
+ } elseif ($artifact -match '\.(zip|rar|7z)$') {
+ $emoji = "๐๏ธ"
+ } else {
+ $emoji = "๐ฆ"
+ }
+
+ $summary += "`n| $emoji [``$artifact``$warning]($downloadUrl) | $sizeFormatted | ``$hash`` |"
+ }
+ }
+ $summary += "`n"
+
+ $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8
- name: Create Release
- uses: softprops/action-gh-release@v2
+ uses: softprops/action-gh-release@v3
with:
files: |
build/cmder.zip
@@ -193,14 +299,20 @@ jobs:
if: startsWith(github.ref, 'refs/tags/')
shell: pwsh
run: |
- echo "### ๐ Release Information" >> $env:GITHUB_STEP_SUMMARY
- echo "" >> $env:GITHUB_STEP_SUMMARY
- echo "Draft release created for tag: **\`${{ github.ref_name }}\`**" >> $env:GITHUB_STEP_SUMMARY
- echo "" >> $env:GITHUB_STEP_SUMMARY
- echo "Release includes:" >> $env:GITHUB_STEP_SUMMARY
- echo "- Full version (\`cmder.zip\`, \`cmder.7z\`)" >> $env:GITHUB_STEP_SUMMARY
- echo "- Mini version (\`cmder_mini.zip\`)" >> $env:GITHUB_STEP_SUMMARY
- echo "- File hashes (\`hashes.txt\`)" >> $env:GITHUB_STEP_SUMMARY
- echo "" >> $env:GITHUB_STEP_SUMMARY
- echo "> โ ๏ธ Release is in **draft** mode. Please review and publish manually." >> $env:GITHUB_STEP_SUMMARY
+ $summary = @"
+
+ ---
+
+ ### Release Information
+
+ ๐ Draft release created for tag: **``${{ github.ref_name }}``**
+
+ Release includes:
+ - Full version (``cmder.zip``, ``cmder.7z``)
+ - Mini version (``cmder_mini.zip``)
+ - File hashes (``hashes.txt``)
+
+ > โ ๏ธ Release is in **draft** mode. Please review and publish manually.
+ "@
+ $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 1497bf9ac..7f66475f1 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -8,7 +8,7 @@ name: "CodeQL"
on:
push:
- branches: [ "master", "development" ]
+ branches: [ "master", "main", "development" ]
paths-ignore:
- '**/*.md'
- '**/*.txt'
@@ -16,7 +16,7 @@ on:
- '**/.gitignore'
pull_request:
# The branches below must be a subset of the branches above
- branches: [ "master", "development" ]
+ branches: [ "master", "main", "development" ]
paths-ignore:
- '**/*.md'
- '**/*.txt'
@@ -50,20 +50,21 @@ jobs:
- name: Summary - CodeQL analysis started
shell: pwsh
run: |
- $summary = @(
- '## ๐ CodeQL Security Analysis - Workflow Summary'
- ''
- '### Analysis Configuration'
- ''
- '| Property | Value |'
- '| --- | --- |'
- '| Repository | `${{ github.repository }}` |'
- '| Branch | `${{ github.ref_name }}` |'
- '| Language | `${{ matrix.language }}` |'
- '| Commit | `${{ github.sha }}` |'
- ''
- )
- $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY
+ $summary = @"
+ ## ๐ CodeQL Security Analysis - Workflow Summary
+
+ ### Analysis Configuration
+
+ | Property | Value |
+ | --- | --- |
+ | Repository | ``${{ github.repository }}`` |
+ | Branch | ``${{ github.ref_name }}`` |
+ | Language | ``${{ matrix.language }}`` |
+ | Commit | ``${{ github.sha }}`` |
+
+ "@
+
+ $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
@@ -78,7 +79,7 @@ jobs:
# queries: security-extended,security-and-quality
- name: Add MSBuild to PATH
- uses: microsoft/setup-msbuild@v2
+ uses: microsoft/setup-msbuild@v3
- name: Build Cmder Launcher
shell: pwsh
@@ -89,13 +90,14 @@ jobs:
if: success()
shell: pwsh
run: |
- $summary = @(
- '### โ
Build Completed'
- ''
- 'Cmder launcher built successfully for CodeQL analysis.'
- ''
- )
- $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY
+ $summary = @"
+ ### โ
Build Completed
+
+ Cmder launcher built successfully for CodeQL analysis.
+
+ "@
+
+ $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
@@ -106,13 +108,14 @@ jobs:
if: success()
shell: pwsh
run: |
- $summary = @(
- '### ๐ CodeQL Analysis Results'
- ''
- 'โ
CodeQL security analysis completed successfully.'
- ''
- '**Language analyzed:** `${{ matrix.language }}`'
- ''
- '> Check the Security tab for detailed findings and recommendations.'
- )
- $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY
+ $summary = @"
+ ### ๐ CodeQL Analysis Results
+
+ โ
CodeQL security analysis completed successfully.
+
+ **Language analyzed:** ``${{ matrix.language }}``
+
+ > Check the Security tab for detailed findings and recommendations.
+ "@
+
+ $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 5110ab18d..667b8e7ab 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -4,6 +4,7 @@ on:
push:
branches:
- master
+ - main
- development
paths-ignore:
- '**/*.md'
@@ -13,6 +14,7 @@ on:
pull_request:
branches:
- master
+ - main
- development
paths-ignore:
- '**/*.md'
@@ -39,20 +41,33 @@ jobs:
steps:
- uses: actions/checkout@v6
+ with:
+ fetch-depth: 0
- name: Summary - Test execution started
shell: pwsh
run: |
- echo "## ๐งช Run Tests - Workflow Summary" >> $env:GITHUB_STEP_SUMMARY
- echo "" >> $env:GITHUB_STEP_SUMMARY
- echo "### Test Environment" >> $env:GITHUB_STEP_SUMMARY
- echo "| Property | Value |" >> $env:GITHUB_STEP_SUMMARY
- echo "| --- | --- |" >> $env:GITHUB_STEP_SUMMARY
- echo "| Repository | \`${{ github.repository }}\` |" >> $env:GITHUB_STEP_SUMMARY
- echo "| Branch | \`${{ github.ref_name }}\` |" >> $env:GITHUB_STEP_SUMMARY
- echo "| Commit | \`${{ github.sha }}\` |" >> $env:GITHUB_STEP_SUMMARY
- echo "| Runner OS | \`${{ runner.os }}\` |" >> $env:GITHUB_STEP_SUMMARY
- echo "" >> $env:GITHUB_STEP_SUMMARY
+ # Get Cmder version
+ . scripts/utils.ps1
+ $cmderVersion = Get-VersionStr
+
+ $summary = @"
+ ## โ
Run Tests - Workflow Summary
+
+ ### Test Environment
+ | Property | Value |
+ | --- | --- |
+ | Repository | ``${{ github.repository }}`` |
+ | Branch | ``${{ github.ref_name }}`` |
+ | Commit | ``${{ github.sha }}`` |
+ | Runner OS | ``${{ runner.os }}`` |
+ | Cmder Version | **$cmderVersion** |
+ | PowerShell Version | **$($PSVersionTable.PSVersion)** |
+ | Event | ``${{ github.event_name }}`` |
+
+ "@
+
+ $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8
- name: Initialize vendors
shell: pwsh
@@ -63,53 +78,127 @@ jobs:
if: success()
shell: pwsh
run: |
- echo "### โ๏ธ Vendor Initialization" >> $env:GITHUB_STEP_SUMMARY
- echo "" >> $env:GITHUB_STEP_SUMMARY
- echo "โ
Vendor dependencies initialized successfully." >> $env:GITHUB_STEP_SUMMARY
- echo "" >> $env:GITHUB_STEP_SUMMARY
+ # Get vendor versions from sources.json
+ $vendorInfo = @()
+ $sources = Get-Content "vendor\sources.json" -Raw | ConvertFrom-Json
+ foreach ($source in $sources) {
+ $dir = $source.name
+ if (-not $dir) {
+ continue
+ }
+ $versionFile = "vendor/$dir/.cmderver"
+ if (Test-Path $versionFile) {
+ $version = Get-Content $versionFile -Raw
+ $vendorInfo += "- **$dir**: $($version.Trim())"
+ }
+ }
+
+ $summary = @"
+ ### โ๏ธ Vendor Initialization
+
+ โ
Vendor dependencies initialized successfully.
+
+ **Vendor Versions:**
+ "@
+
+ $(
+ if ($vendorInfo.Count -eq 0) {
+ $summary += "_No vendor version information available._"
+ } else {
+ $summary += $vendorInfo -join "`n"
+ }
+ )
+
+ $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8
- name: Summary - Test results table header
if: success()
shell: pwsh
run: |
- echo "### ๐ Test Results" >> $env:GITHUB_STEP_SUMMARY
- echo "" >> $env:GITHUB_STEP_SUMMARY
- echo "| Test | Status |" >> $env:GITHUB_STEP_SUMMARY
- echo "| --- | --- |" >> $env:GITHUB_STEP_SUMMARY
+ $summary = @"
+ ### ๐ Test Results
+
+ | Test | Status | Duration |
+ | --- | --- | --- |
+ "@
+
+ $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8
- name: Testing Clink Shell
+ id: test-clink
+ shell: pwsh
run: |
+ $startTime = Get-Date
cmd /c vendor\init.bat /v /d /t
+ $duration = [math]::Round(((Get-Date) - $startTime).TotalSeconds, 2)
+ echo "duration=$duration" >> $env:GITHUB_OUTPUT
- name: Summary - Clink Shell test
if: success()
shell: pwsh
run: |
- echo "| Clink Shell | โ
Passed |" >> $env:GITHUB_STEP_SUMMARY
+ $duration = "${{ steps.test-clink.outputs.duration }}"
+ if ($duration) {
+ $duration = "$duration s"
+ } else {
+ $duration = "N/A"
+ }
+ "| Clink Shell | โ
Passed | $duration |" | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8
- name: Testing PowerShell
+ id: test-powershell
+ shell: pwsh
run: |
+ $startTime = Get-Date
PowerShell.exe -ExecutionPolicy Bypass -NoLogo -NoProfile -Command "$env:CMDER_DEBUG='1'; . 'vendor\profile.ps1'"
+ $duration = [math]::Round(((Get-Date) - $startTime).TotalSeconds, 2)
+ echo "duration=$duration" >> $env:GITHUB_OUTPUT
- name: Summary - PowerShell test
if: success()
shell: pwsh
run: |
- echo "| PowerShell | โ
Passed |" >> $env:GITHUB_STEP_SUMMARY
+ $duration = "${{ steps.test-powershell.outputs.duration }}"
+ if ($duration) {
+ $duration = "$duration s"
+ } else {
+ $duration = "N/A"
+ }
+ "| PowerShell | โ
Passed | $duration |" | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8
- name: Testing Bash
+ id: test-bash
+ shell: pwsh
run: |
+ $startTime = Get-Date
bash vendor/cmder.sh
+ $duration = [math]::Round(((Get-Date) - $startTime).TotalSeconds, 2)
+ echo "duration=$duration" >> $env:GITHUB_OUTPUT
- name: Summary - Bash test
if: success()
shell: pwsh
run: |
- echo "| Bash | โ
Passed |" >> $env:GITHUB_STEP_SUMMARY
+ $duration = "${{ steps.test-bash.outputs.duration }}"
+ if ($duration) {
+ $duration = "$duration s"
+ } else {
+ $duration = "N/A"
+ }
+ "| Bash | โ
Passed | $duration |" | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8
- name: Summary - All tests completed
if: success()
shell: pwsh
run: |
- echo "" >> $env:GITHUB_STEP_SUMMARY
- echo "### โ
All Tests Completed" >> $env:GITHUB_STEP_SUMMARY
- echo "" >> $env:GITHUB_STEP_SUMMARY
- echo "All shell environments tested successfully!" >> $env:GITHUB_STEP_SUMMARY
+ $summary = @"
+
+ ### โ
All Tests Completed
+
+ All shell environments tested successfully!
+
+ **Test Coverage:**
+ - โ
Clink shell environment (Windows cmd.exe with Clink)
+ - โ
PowerShell environment (with Cmder profile)
+ - โ
Bash environment (Git Bash integration)
+ "@
+
+ $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8
diff --git a/.github/workflows/vendor.yml b/.github/workflows/vendor.yml
index ab254aedf..b464a5370 100644
--- a/.github/workflows/vendor.yml
+++ b/.github/workflows/vendor.yml
@@ -31,61 +31,63 @@ jobs:
- name: Summary - Workflow started
shell: pwsh
run: |
- $summary = @(
- '## ๐ฆ Update Vendor - Workflow Summary'
- ''
- 'Checking for vendor dependency updates...'
- ''
- )
- $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY
+ $summary = @"
+ ## ๐ฆ Update Vendor - Workflow Summary
+
+ Checking for vendor dependency updates...
+
+ "@
+
+ $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8
- id: make-changes
name: Checking for updates
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
- $currentVersion = (Get-Content .\vendor\sources.json | ConvertFrom-Json)
- . .\scripts\update.ps1 -verbose
- Set-GHVariable -Name COUNT_UPDATED -Value $count
- $newVersion = (Get-Content .\vendor\sources.json | ConvertFrom-Json)
- $listUpdated = ""
- $updateMessage = "| Name | Old Version | New Version |`n| :--- | ---- | ---- |`n"
- foreach ($s in $newVersion) {
- $oldVersion = ($currentVersion | Where-Object {$_.name -eq $s.name}).version
- if ($s.version -ne $oldVersion) {
- $repoUrl = ($repoUrl = $s.Url.Replace("/archive/", "/releases/")).Substring(0, $repoUrl.IndexOf("/releases/")) + "/releases"
- $listUpdated += "$($s.name) v$($s.version), "
- $updateMessage += "| **[$($s.name)]($repoUrl)** | $oldVersion | **$($s.version)** |`n"
- }
+ $currentVersion = (Get-Content -Raw .\vendor\sources.json | ConvertFrom-Json)
+ . .\scripts\update.ps1 -verbose
+ Set-GHVariable -Name COUNT_UPDATED -Value $count
+ $newVersion = (Get-Content -Raw .\vendor\sources.json | ConvertFrom-Json)
+ $listUpdated = ""
+ $updateMessage = "| Name | Old Version | New Version |`n| :--- | ---- | ---- |`n"
+ foreach ($s in $newVersion) {
+ $oldVersion = ($currentVersion | Where-Object {$_.name -eq $s.name}).version
+ if ($s.version -ne $oldVersion) {
+ $repoUrl = ($repoUrl = $s.Url.Replace("/archive/", "/releases/")).Substring(0, $repoUrl.IndexOf("/releases/")) + "/releases"
+ $listUpdated += "$($s.name) v$($s.version), "
+ $updateMessage += "| **[$($s.name)]($repoUrl)** | $oldVersion | **$($s.version)** |`n"
}
- if ($count -eq 0) { return }
- Set-GHVariable -Name LIST_UPDATED -Value $listUpdated.Trim(', ')
- echo "UPDATE_MESSAGE<< 0
with:
@@ -103,15 +105,16 @@ jobs:
if: env.COUNT_UPDATED > 0
shell: pwsh
run: |
- $summary = @(
- '### ๐ Pull Request Created'
- ''
- 'A pull request has been created to update the vendor dependencies.'
- ''
- '**Branch:** `update-vendor`'
- ''
- $env:LIST_UPDATED -and "**Updated dependencies:** $env:LIST_UPDATED" -or "**Updated dependencies:** "
- ''
- '> Please review and merge the pull request to apply the updates.'
- )
- $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY
+ $summary = @"
+ ### ๐ Pull Request Created
+
+ A pull request has been created to update the vendor dependencies.
+
+ **Branch:** ``update-vendor``
+
+ **Updated dependencies:** $env:LIST_UPDATED
+
+ > Please review and merge the pull request to apply the updates.
+ "@
+
+ $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8
diff --git a/.gitignore b/.gitignore
index 3ca812444..8edad6f19 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,4 +37,4 @@ scripts/packer/iso/*.iso
scripts/packer/packer_cache
scripts/packer/output-*
*.box
-
+*.code-workspace
diff --git a/scripts/build.ps1 b/scripts/build.ps1
index 634d2467c..d80fe03a6 100644
--- a/scripts/build.ps1
+++ b/scripts/build.ps1
@@ -8,6 +8,47 @@
You will need to make this script executable by setting your Powershell Execution Policy to Remote signed
Then unblock the script for execution with UnblockFile .\build.ps1
+.PARAMETER sourcesPath
+ Path to the vendor sources JSON file. Defaults to vendor/sources.json.
+
+ Use this to point to a custom package manifest.
+.PARAMETER saveTo
+ Destination directory for downloaded and extracted vendor dependencies.
+
+ Defaults to the repository vendor directory.
+.PARAMETER launcher
+ Path to the launcher project directory used when -Compile is set.
+
+ Defaults to the repository launcher directory.
+.PARAMETER config
+ Path to the configuration directory used to back up and restore user-modified
+ terminal settings during vendor refresh.
+
+ Defaults to the repository config directory.
+.PARAMETER noVendor
+ Skip downloading and extracting all vendors.
+
+ Useful with -Compile when only rebuilding the launcher.
+.PARAMETER terminal
+ Select which terminal packages to include from sources:
+ - all: include all supported terminal packages (default)
+ - none: skip terminal vendor downloads
+ - conemu-maximus5: include only ConEmu package
+ - windows-terminal: include only Windows Terminal package
+.PARAMETER Compile
+ Build the launcher executable using MSBuild.
+
+ Requires Visual C++ build tools and msbuild in PATH.
+.PARAMETER InstallPacman
+ Install pacman in the bundled Git for Windows environment if it is not present.
+.PARAMETER Verbose
+ Built-in common parameter from CmdletBinding.
+
+ Prints detailed progress output for troubleshooting.
+.PARAMETER WhatIf
+ Built-in common parameter from CmdletBinding (SupportsShouldProcess).
+
+ Does a dry-run of the build process, showing what actions would be taken without making changes.
.EXAMPLE
.\build.ps1
@@ -21,20 +62,41 @@
Skip all downloads and only build launcher.
.EXAMPLE
- .\build -verbose
+ .\build.ps1 -Verbose
Execute the build and see what's going on.
.EXAMPLE
- .\build.ps1 -SourcesPath '~/custom/vendors.json'
+ .\build.ps1 -SourcesPath 'C:\custom\sources.json'
Build Cmder with your own packages. See vendor/sources.json for the syntax you need to copy.
+.EXAMPLE
+ .\build.ps1 -Terminal conemu-maximus5
+
+ Build Cmder including only ConEmu (skips Windows Terminal).
+.EXAMPLE
+ .\build.ps1 -Terminal windows-terminal
+
+ Build Cmder including only Windows Terminal (skips ConEmu).
+.EXAMPLE
+ .\build.ps1 -Terminal none -Compile
+
+ Build launcher only and skip all terminal vendor downloads.
+.EXAMPLE
+ .\build.ps1 -InstallPacman
+
+ Build vendors and install pacman into the bundled Git for Windows environment if missing.
+.EXAMPLE
+ .\build.ps1 -WhatIf
+
+ Shows what actions would be taken without applying changes.
.NOTES
AUTHORS
- Samuel Vasko, Jack Bennett
+ Samuel Vasko, Jack Bennett, Dax Games
Part of the Cmder project.
.LINK
http://cmder.app/ - Project Home
#>
+
[CmdletBinding(SupportsShouldProcess = $true)]
Param(
# CmdletBinding will give us;
@@ -60,7 +122,10 @@ Param(
[string]$terminal = 'all',
# Build launcher if you have MSBuild tools installed
- [switch]$Compile
+ [switch]$Compile,
+
+ # Install pacman if not present
+ [switch]$InstallPacman
)
# Get the scripts and cmder root dirs we are building in.
@@ -199,6 +264,19 @@ if (-not $noVendor) {
Copy-Item $($saveTo + "git-prompt.sh") $($saveTo + "git-for-windows/etc/profile.d/git-prompt.sh")
}
+ $gitForWindowsPath = $saveTo + "git-for-windows"
+ $pacmanPath = $saveTo + "git-for-windows/usr/bin/pacman.exe"
+
+ $shouldInstallPacman =
+ $InstallPacman -and
+ (Test-Path $gitForWindowsPath) -and
+ -not (Test-Path $pacmanPath)
+
+ if ($shouldInstallPacman) {
+ Write-Verbose "Installing pacman..."
+ & $($saveTo + "git-for-windows/bin/bash.exe") $($saveTo + "../scripts/install_pacman.sh")
+ }
+
Pop-Location
}
diff --git a/scripts/install_pacman.sh b/scripts/install_pacman.sh
new file mode 100644
index 000000000..fa9c1f079
--- /dev/null
+++ b/scripts/install_pacman.sh
@@ -0,0 +1,133 @@
+#!/usr/bin/env bash
+
+# Based on: https://github.com/mcgitty/pacman-for-git
+# Dax T. Games Fork: https://github.com/daxgames/pacman-for-git
+
+# Disclaimer: Use at your own risk.
+#
+# This script modifies system files and installs the pacman package manager into your Git for Windows environment.
+#
+# While it has been tested in various Git for Windows versions, there is always a risk of data loss or system instability when running scripts that alter executable files and shared libraries.
+#
+# Make sure to back up any important data before proceeding.
+#
+# Always review and understand scripts from external sources prior to execution.
+export bin_source=${1:-https://github.com/daxgames/pacman-for-git/raw/refs/heads/main}
+echo "Using binary source: $bin_source"
+echo "Using HOME directory: $HOME"
+read -rp "Press [Enter] to continue..."
+
+if [[ "$HOSTTYPE" == "i686" ]]; then
+ pacman=(
+ pacman-6.0.0-4-i686.pkg.tar.zst
+ pacman-mirrors-20210703-1-any.pkg.tar.zst
+ msys2-keyring-1~20210213-2-any.pkg.tar.zst
+ )
+
+ zstd=zstd-1.5.0-1-i686.pkg.tar.xz
+ zstd_win=https://github.com/facebook/zstd/releases/download/v1.5.5/zstd-v1.5.5-win32.zip
+else
+ pacman=(
+ pacman-6.0.1-18-x86_64.pkg.tar.zst
+ pacman-mirrors-20220205-1-any.pkg.tar.zst
+ msys2-keyring-1~20220623-1-any.pkg.tar.zst
+ )
+
+ zstd=zstd-1.5.2-1-x86_64.pkg.tar.xz
+ zstd_win=https://github.com/facebook/zstd/releases/download/v1.5.5/zstd-v1.5.5-win64.zip
+fi
+
+echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+echo Downloading pacman files...
+echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+for f in "${pacman[@]}"; do
+ [[ -f "$HOME/Downloads/$f" ]] && continue
+ echo "Running: curl -sLkf -o \"$HOME/Downloads/$f\" \"${bin_source}/$f\""
+ curl -sLkf -o "$HOME/Downloads/$f" "${bin_source}/$f" || exit 1
+done
+echo -e "\n=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"
+
+echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+echo Downloading zstd binaries...
+echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+if [[ ! -f "$HOME/Downloads/$zstd" ]] ; then
+ echo "Running: curl -sLkf -o \"$HOME/Downloads/$zstd\" \"${bin_source}/$zstd\""
+ curl -sLkf -o "$HOME/Downloads/$zstd" "${bin_source}/$zstd" || exit 1
+fi
+
+if [[ ! -f "$HOME/Downloads/$(basename${zstd_win})" ]] ; then
+ echo "Running: curl -sLkf -o \"$HOME/Downloads/$(basename \"${zstd_win}\")\" \"$zstd_win\""
+ curl -sLkf -o "$HOME/Downloads/$(basename "${zstd_win}")" "$zstd_win" || exit 1
+fi
+echo -e "\n=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"
+
+echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+echo Downloading pacman.conf...
+echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+echo "Running: curl -Lk https://raw.githubusercontent.com/msys2/MSYS2-packages/7858ee9c236402adf569ac7cff6beb1f883ab67c/pacman/pacman.conf"
+curl -sLk https://raw.githubusercontent.com/msys2/MSYS2-packages/7858ee9c236402adf569ac7cff6beb1f883ab67c/pacman/pacman.conf -o /etc/pacman.conf || exit 1
+
+pushd "$HOME/Downloads"
+[[ -d "$(basename "${zstd_win}" | sed 's/\.zip$//')" ]] && \
+ rm -rf "$(basename "${zstd_win}" | sed 's/\.zip$//')"
+unzip "$HOME/Downloads/$(basename "${zstd_win}")"
+export PATH="$PATH:$HOME/Downloads/$(basename "${zstd_win}" | sed 's/\.zip$//')"
+popd
+echo -e "\n=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"
+
+cd /
+echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+echo Installing pacman files...
+echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+echo "Extracting zstd to /usr..."
+tar x --xz -vf "$HOME/Downloads/$zstd" usr
+
+for f in "${pacman[@]}"; do
+ echo "Extracting $f to /usr and /etc..."
+ tar x --zstd -vf "$HOME/Downloads/$f" usr etc 2>/dev/null
+done
+echo -e "\n=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"
+
+echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+echo Initializing pacman...
+echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+mkdir -p /var/lib/pacman
+ln -sf "$(which gettext)" /usr/bin/
+pacman-key --init
+pacman-key --populate msys2
+pacman -Syu --noconfirm --disable-download-timeout
+echo -e "\n=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"
+
+echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+echo Getting package versions for the installed Git release
+echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+t=$(grep -E 'mingw-w64-[ix_0-9]+-git ' /etc/package-versions.txt)
+echo "Found package version line: $t"
+
+curl --help >/dev/null 2>&1 || { echo "ERROR: curl is not installed properly."; exit 1; }
+
+echo "Getting commit ID that matches '$t' from github pacman-for-git..."
+t=$(curl -sLk "${bin_source}/version-tags.txt" | grep "$t")
+echo "Full line from version-tags.txt: '$t'"
+
+[[ "$t" == "" ]] && echo "ERROR: Commit ID not logged in github pacman-for-git." && exit 1
+echo -e "Using commit ID: '${t##* }'"
+echo -e "\n=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"
+
+echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+echo Downloading package database files for the installed Git release
+echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+b=64 && [[ "$t" == *-i686-* ]] && b=32
+URL="https://github.com/git-for-windows/git-sdk-$b/raw/${t##* }"
+while read -r p v; do
+ d="/var/lib/pacman/local/$p-$v"
+ mkdir -p "$d"
+ echo "$d"
+
+ for f in desc files mtree; do
+ curl -fsSL "$URL$d/$f" -o "$d/$f"
+ done
+
+ [[ ! -f "$d/desc" ]] && rmdir "$d" && echo "Missing $d"
+done < /etc/package-versions.txt
+echo -e "\n=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"
diff --git a/scripts/pack.ps1 b/scripts/pack.ps1
index 00e862592..8968a431d 100644
--- a/scripts/pack.ps1
+++ b/scripts/pack.ps1
@@ -6,14 +6,60 @@
You will need to make this script executable by setting your Powershell Execution Policy to Remote signed
Then unblock the script for execution with UnblockFile .\pack.ps1
+.PARAMETER cmderRoot
+ Path to the Cmder repository root that should be packaged.
+
+ Defaults to the parent directory of this script.
+.PARAMETER terminal
+ Select which terminal package set is included in generated archives:
+ - all: create all archive variants (default)
+ - none: exclude both ConEmu and Windows Terminal packages
+ - conemu-maximus5: include only ConEmu package
+ - windows-terminal: include only Windows Terminal package
+.PARAMETER saveTo
+ Output directory where archives and hashes.txt are written.
+
+ Defaults to the repository build directory.
+.PARAMETER Verbose
+ Built-in common parameter from CmdletBinding.
+
+ Prints detailed packaging progress and included files.
+.PARAMETER WhatIf
+ Built-in common parameter from CmdletBinding (SupportsShouldProcess).
+
+ Shows what actions would run without making changes.
.EXAMPLE
.\pack.ps1
Creates default archives for Cmder
.EXAMPLE
- .\pack.ps1 -verbose
+ .\pack.ps1 -Verbose
Creates default archives for Cmder with plenty of information
+.EXAMPLE
+ .\pack.ps1 -Terminal none
+
+ Create archives without bundled terminal emulator packages.
+.EXAMPLE
+ .\pack.ps1 -Terminal conemu-maximus5
+
+ Create archives that include ConEmu and exclude Windows Terminal.
+.EXAMPLE
+ .\pack.ps1 -Terminal windows-terminal
+
+ Create archives that include Windows Terminal and exclude ConEmu.
+.EXAMPLE
+ .\pack.ps1 -SaveTo 'C:\temp\cmder-artifacts'
+
+ Write release archives and hashes.txt to a custom output directory.
+.EXAMPLE
+ .\pack.ps1 -CmderRoot 'C:\src\cmder'
+
+ Package a Cmder checkout from a custom repository path.
+.EXAMPLE
+ .\pack.ps1 -WhatIf
+
+ Preview packaging actions without creating or deleting files.
.NOTES
AUTHORS
Samuel Vasko, Jack Bennett, Martin Kemp
@@ -56,12 +102,6 @@ if ($terminal -eq "none") {
"cmder_wt.zip" = "-mm=Deflate -mfb=128 -mpass=3 -xr!`"vendor\conemu-maximus5`"";
"cmder_wt_mini.zip" = "-xr!`"vendor\git-for-windows`" -xr!`"vendor\conemu-maximus5`"";
}
-} elseif ($terminal -eq "windows-terminal") {
- $targets = @{
- "cmder.7z" = "-t7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -ms=on -myx=7 -mqs=on -xr!`"vendor\windows-terminal`"";
- "cmder.zip" = "-mm=Deflate -mfb=128 -mpass=3 -xr!`"vendor\windows-terminal`"";
- "cmder_mini.zip" = "-xr!`"vendor\git-for-windows`" -xr!`"vendor\windows-terminal`"";
- }
} else {
$targets = @{
"cmder_win.7z" = "-t7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -ms=on -myx=7 -mqs=on -xr!`"vendor\conemu-maximus5`" -xr!`"vendor\windows-terminal`"";
@@ -99,7 +139,7 @@ if ($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent) {
foreach ($t in $targets.GetEnumerator()) {
Create-Archive "$cmderRoot" "$saveTo\$($t.Name)" $t.Value
$hash = (Digest-Hash "$saveTo\$($t.Name)")
- Add-Content -path "$saveTo\hashes.txt" -value ($t.Name + ' ' + $hash)
+ Add-Content -path "$saveTo\hashes.txt" -value ($t.Name + "`t" + $hash)
}
Pop-Location
diff --git a/scripts/utils.ps1 b/scripts/utils.ps1
index 58955407c..f1a175221 100644
--- a/scripts/utils.ps1
+++ b/scripts/utils.ps1
@@ -249,3 +249,107 @@ function Download-File {
$wc.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials;
$wc.DownloadFile($Url, $File)
}
+
+function Format-FileSize {
+ <#
+ .SYNOPSIS
+ Formats a file size in bytes to a human-readable string using binary units.
+
+ .DESCRIPTION
+ Converts file sizes to appropriate binary units (B, KiB, MiB, GiB) for better readability.
+
+ .PARAMETER Bytes
+ The file size in bytes to format.
+
+ .EXAMPLE
+ Format-FileSize -Bytes 1024
+ Returns "1.00 KiB"
+
+ .EXAMPLE
+ Format-FileSize -Bytes 15728640
+ Returns "15.00 MiB"
+ #>
+ param(
+ [Parameter(Mandatory = $true)]
+ [double]$Bytes
+ )
+
+ if ($Bytes -ge 1GB) {
+ return "{0:N2} GiB" -f ($Bytes / 1GB)
+ } elseif ($Bytes -ge 1MB) {
+ return "{0:N2} MiB" -f ($Bytes / 1MB)
+ } elseif ($Bytes -ge 1KB) {
+ return "{0:N2} KiB" -f ($Bytes / 1KB)
+ } else {
+ return "{0:N0} B" -f $Bytes
+ }
+}
+
+function Get-ArtifactDownloadUrl {
+ <#
+ .SYNOPSIS
+ Retrieves the download URL for a GitHub Actions artifact with retry logic.
+
+ .DESCRIPTION
+ Uses the GitHub CLI to fetch artifact information from the GitHub API with automatic retries.
+ Falls back to returning $null if all attempts fail.
+
+ .PARAMETER ArtifactName
+ The name of the artifact to retrieve the download URL for.
+
+ .PARAMETER Repository
+ The GitHub repository in the format "owner/repo".
+
+ .PARAMETER RunId
+ The GitHub Actions workflow run ID.
+
+ .PARAMETER MaxRetries
+ Maximum number of retry attempts. Default is 3.
+
+ .PARAMETER DelaySeconds
+ Delay in seconds between retry attempts. Default is 2.
+
+ .EXAMPLE
+ Get-ArtifactDownloadUrl -ArtifactName "cmder.zip" -Repository "cmderdev/cmder" -RunId "123456789"
+
+ .EXAMPLE
+ Get-ArtifactDownloadUrl -ArtifactName "build-output" -Repository "owner/repo" -RunId "987654321" -MaxRetries 5 -DelaySeconds 3
+ #>
+ param(
+ [Parameter(Mandatory = $true)]
+ [string]$ArtifactName,
+
+ [Parameter(Mandatory = $true)]
+ [string]$Repository,
+
+ [Parameter(Mandatory = $true)]
+ [string]$RunId,
+
+ [int]$MaxRetries = 3,
+ [int]$DelaySeconds = 2
+ )
+
+ for ($i = 0; $i -lt $MaxRetries; $i++) {
+ try {
+ # Use GitHub CLI to get artifact information
+ $artifactsJson = gh api "repos/$Repository/actions/runs/$RunId/artifacts" --jq ".artifacts[] | select(.name == `"$ArtifactName`")"
+
+ if ($artifactsJson) {
+ $artifact = $artifactsJson | ConvertFrom-Json
+ if ($artifact.id) {
+ # Construct browser-accessible GitHub Actions artifact download URL
+ # Format: https://github.com/owner/repo/actions/runs/{run_id}/artifacts/{artifact_id}
+ return "https://github.com/$Repository/actions/runs/$RunId/artifacts/$($artifact.id)"
+ }
+ }
+ } catch {
+ Write-Host "Attempt $($i + 1) failed to get artifact URL for $ArtifactName : $_"
+ }
+
+ if ($i -lt ($MaxRetries - 1)) {
+ Start-Sleep -Seconds $DelaySeconds
+ }
+ }
+
+ return $null
+}
diff --git a/vendor/sources.json b/vendor/sources.json
index df1ae3e5f..3f6118fc1 100644
--- a/vendor/sources.json
+++ b/vendor/sources.json
@@ -1,13 +1,13 @@
[
{
"name": "git-for-windows",
- "version": "2.52.0.windows.1",
- "url": "https://github.com/git-for-windows/git/releases/download/v2.52.0.windows.1/PortableGit-2.52.0-64-bit.7z.exe"
+ "version": "2.54.0.windows.1",
+ "url": "https://github.com/git-for-windows/git/releases/download/v2.54.0.windows.1/PortableGit-2.54.0-64-bit.7z.exe"
},
{
"name": "clink",
- "version": "1.9.5",
- "url": "https://github.com/chrisant996/clink/releases/download/v1.9.5/clink.1.9.5.ee6b4f.zip"
+ "version": "1.9.17",
+ "url": "https://github.com/chrisant996/clink/releases/download/v1.9.17/clink.1.9.17.36e2ca.zip"
},
{
"name": "conemu-maximus5",
@@ -16,8 +16,8 @@
},
{
"name": "windows-terminal",
- "version": "1.23.12811.0",
- "url": "https://github.com/microsoft/terminal/releases/download/v1.23.12811.0/Microsoft.WindowsTerminal_1.23.12811.0_x64.zip"
+ "version": "1.23.20211.0",
+ "url": "https://github.com/microsoft/terminal/releases/download/v1.23.20211.0/Microsoft.WindowsTerminal_1.23.20211.0_x64.zip"
},
{
"name": "clink-completions",