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",