diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 9ef6c2a..d08569d 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,7 +1,7 @@ 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 76d0298..4f0581d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -128,10 +128,10 @@ jobs: 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 '- ✅ `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 - name: Create Release diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index fccf046..5255be7 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -50,17 +50,20 @@ jobs: - name: Summary - CodeQL analysis started shell: pwsh run: | - echo "## 🔒 CodeQL Security Analysis - Workflow Summary" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "### Analysis Configuration" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $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 "| Language | \`${{ matrix.language }}\` |" >> $env:GITHUB_STEP_SUMMARY - echo "| Commit | \`${{ github.sha }}\` |" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $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 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL @@ -86,10 +89,14 @@ jobs: if: success() shell: pwsh run: | - echo "### ✅ Build Completed" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "Cmder launcher built successfully for CodeQL analysis." >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY + $summary = @" + ### ✅ Build Completed + + Cmder launcher built successfully for CodeQL analysis. + + "@ + + $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v4 @@ -100,12 +107,14 @@ jobs: if: success() shell: pwsh run: | - @" - ### 🔍 CodeQL Analysis Results - - ✅ CodeQL security analysis completed successfully. - - **Language analyzed:** ``${{ matrix.language }}`` - - > Check the Security tab for detailed findings and recommendations. - "@ | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8 + $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 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5110ab1..cf08d32 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -39,6 +39,8 @@ jobs: steps: - uses: actions/checkout@v6 + with: + fetch-depth: 0 - name: Summary - Test execution started shell: pwsh diff --git a/.github/workflows/vendor.yml b/.github/workflows/vendor.yml index c779122..43a3f5e 100644 --- a/.github/workflows/vendor.yml +++ b/.github/workflows/vendor.yml @@ -31,10 +31,14 @@ jobs: - name: Summary - Workflow started shell: pwsh run: | - echo "## 📦 Vendor Update - Workflow Summary" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "🔍 Checking for vendor dependency updates..." >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY + $summary = @" + ## 📦 Update Vendor - Workflow Summary + + 🔍 Checking for vendor dependency updates... + + "@ + + $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY - id: make-changes name: Checking for updates @@ -156,33 +160,38 @@ jobs: - name: Summary - Update check results shell: pwsh run: | - $count = $env:COUNT_UPDATED + $count = [int]$env:COUNT_UPDATED + if ($count -eq 0) { - echo "### ✅ No Updates Available" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "All vendor dependencies are up to date! 🎉" >> $env:GITHUB_STEP_SUMMARY + $summary = @" + ### ✅ No Updates Available + + All vendor dependencies are up to date! 🎉 + "@ } else { $word = if ($count -eq 1) { 'dependency' } else { 'dependencies' } - echo "### 🔄 Updates Found" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - if ($count -eq 1) { - echo "📦 **$env:SINGLE_DEP_NAME** updated from \`$env:SINGLE_DEP_OLD_VERSION\` to \`$env:SINGLE_DEP_NEW_VERSION\`" >> $env:GITHUB_STEP_SUMMARY - } else { - echo "📦 **$count** vendor $word updated:" >> $env:GITHUB_STEP_SUMMARY - } - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "$env:UPDATE_MESSAGE" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY + $summary = @" + ### 🔄 Updates Found - # Check if we can auto-merge (only minor/patch changes) - $hasBreaking = $env:HAS_BREAKING_CHANGES -eq 'True' - if ($hasBreaking) { - echo "> ⚠️ **Note:** This update contains major version changes that may include breaking changes." >> $env:GITHUB_STEP_SUMMARY - } else { - echo "> ℹ️ **Note:** This update only contains minor or patch changes." >> $env:GITHUB_STEP_SUMMARY - } + 📦 **$env:SINGLE_DEP_NAME** updated from ``$env:SINGLE_DEP_OLD_VERSION`` to ``$env:SINGLE_DEP_NEW_VERSION`` + + 📦 **$count** vendor $word updated: + + "@ } + $summary += "$env:UPDATE_MESSAGE" + + # Check if we can auto-merge (only minor/patch changes) + $hasBreaking = $env:HAS_BREAKING_CHANGES -eq 'True' + if ($hasBreaking) { + $summary += "> ⚠️ **Note:** This update contains major version changes that may include breaking changes." + } else { + $summary += "> ℹ️ **Note:** This update only contains minor or patch changes." + } + + $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY + - name: Auto-merge minor updates if: env.COUNT_UPDATED > 0 && env.HAS_BREAKING_CHANGES != 'True' shell: pwsh @@ -252,18 +261,26 @@ jobs: if: env.COUNT_UPDATED > 0 && (env.HAS_BREAKING_CHANGES == 'True' || env.AUTO_MERGED == 'false') shell: pwsh run: | - echo "### 🎉 Pull Request Created" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "A pull request has been created to update the vendor dependencies." >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "**Branch:** \`update-vendor\`" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "**Updated dependencies:** $env:LIST_UPDATED" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY + $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:** + + "@ + if ($env:HAS_BREAKING_CHANGES -eq 'True') { - echo "> ⚠️ **Manual review required:** This update contains major version changes." >> $env:GITHUB_STEP_SUMMARY + $summary += "> ⚠️ **Manual review required:** This update contains major version changes." } else { - echo "> ℹ️ **Note:** Auto-merge failed, manual review required." >> $env:GITHUB_STEP_SUMMARY + $summary += "> ℹ️ **Note:** Auto-merge failed, manual review required." } - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "Please review and merge the pull request to apply the updates." >> $env:GITHUB_STEP_SUMMARY + + $summary += @" + > Please review and merge the pull request to apply the updates. + + "@ + + $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b22a19..eca18db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,84 @@ # Change Log +## [1.3.25](https://github.com/cmderdev/cmder/tree/v1.3.25) (2024-05-31) + +### Changes + +- Component Updates + - Update Git for Windows to 2.45.1.windows.1. + - Update ConEmu to 24.05.31. + - Clink 1.6.14. + - clink-completions 0.5.2. + +- Add `SECURITY.md` and refresh CI workflows and actions. +- Enable `match.expand_envvars` and improve git diagnostics for improper versions. + +### Fixes + +- Fix #2944. +- Fix script error when the working directory contains `%`. +- Remove environment refresh race condition. + +## [1.3.24](https://github.com/cmderdev/cmder/tree/v1.3.24) (2023-07-24) + +### Changes + +- Update `build.yml` workflow. + +## [1.3.23](https://github.com/cmderdev/cmder/tree/v1.3.23) (2023-07-24) + +### Changes + +- Update ConEmu (conemu-maximus5) to 23.07.24. + +## [1.3.22](https://github.com/cmderdev/cmder/tree/v1.3.22) (2023-07-24) + +### Changes + +- Handle Clink injction differently in `init.bat`. +- Changes to `clink_settings.lua.default`. + - Do not add commands to Clink Command Line History that begin with whitespace as a default. + - This can be changed to the old behavior by setting `history_ignore_space` to `0` in `config\clink_settings.lua`. + - `history.max_lines` is now defaults to `25000` instead of `10000`. + - This can be changed back to the old behavior by setting `history_max_lines` to `10000` in `config\clink_settings.lua`. + - `history.shared` now defaults to `False` instead of `True`. + - The previous default of `True` was causing issues with some users when using Cmder in multiple sessions. + - This can be changed back to the old behavior by setting `history_shared` to `1` in `config\clink_settings.lua`. + +- Component Updates + - Git for Windows to 2.41.0.windows.3 + - Clink to 1.5.1 + - ConEmu to 23.07.23 + - clink-completions to 0.4.10 + +- Remove AppVeyor configuration and add CodeQL scanning and Dependabot updates. + +### Fixes + +- Fix `/task ""` handling. +- Skip clink injection when initialization fails fatally. +- Fix errors when git/svn/hg are not installed and in profile.d PowerShell scripts. + +## [1.3.21](https://github.com/cmderdev/cmder/tree/v1.3.21) (2022-12-19) + +### Fixes + +- Fix #2789. +- Fix Git Bash `GIT_INSTALL_ROOT` handling. + +### Changes + +- Refactor `clink.lua` to speed up the prompt. +- Refactor and Cleanup `init.bat` and related scripts. +- Refactor and Cleanup `profile.ps1` and related scripts. +- Remove handling of `clink` and `tcc` incompatibility. +- Update ConEmu to mitigate CVE-2022-46387. +- Update Git for Windows to 2.39.0.windows.1 and Clink to 1.4.4. + +### Adds + +- Add `show_warning` function to `vendor\lib\lib_console.cmd` for showing warning messages in yellow. + ## [1.3.20](https://github.com/cmderdev/cmder/tree/v1.3.20) (2022-03-18) ### Changes diff --git a/vendor/clink.lua b/vendor/clink.lua index 81b4d1e..804f9c6 100644 --- a/vendor/clink.lua +++ b/vendor/clink.lua @@ -324,7 +324,7 @@ end -- Find out current branch -- @return {nil|git branch name} --- -local function get_git_branch(git_dir) +local function get_git_branch(git_dir, fast) git_dir = git_dir or get_git_dir() -- If git directory not found then we're probably outside of repo @@ -341,8 +341,90 @@ local function get_git_branch(git_dir) -- if HEAD matches branch expression, then we're on named branch -- otherwise it is a detached commit local branch_name = HEAD:match('ref: refs/heads/(.+)') + if os.getenv("CLINK_DEBUG_GIT_REFTABLE") then + branch_name = '.invalid' + end - return branch_name or 'HEAD detached at '..HEAD:sub(1, 7) + -- If the branch name is ".invalid" and the fast method wasn't requested, + -- then invoke git.exe to get accurate current branch info (slow method). + if branch_name == ".invalid" and not fast then + local file + branch_name = nil + + -- Handle the most common case first. + if not branch_name then + file = io_popenyield("git --no-optional-locks branch 2>nul") + if file then + for line in file:lines() do + local b = line:match("^%*%s+(.*)") + if b then + b = b:match("^%((HEAD detached at .*)%)") or b + branch_name = b + break + end + end + file:close() + end + end + + -- Handle the cases where "git branch" output is empty, but "git + -- branch --show-current" shows the branch name (e.g. a new repo). + if not branch_name then + file = io_popenyield("git --no-optional-locks branch --show-current 2>nul") + if file then + for line in file:lines() do -- luacheck: ignore 512 + branch_name = line + break + end + file:close() + end + end + else + branch_name = branch_name or 'HEAD detached at '..HEAD:sub(1, 7) + end + + return branch_name +end + +local function get_git_remote(git_dir, branch) + if not git_dir then return nil end + if not branch then return nil end + + local file = io.open(git_dir.."/config", 'r') + if not file then return nil end + + local git_config = {} + + local function get_git_config_value(section, param) + return git_config[section] and git_config[section][param] or nil + end + + local section + for line in file:lines() do + if (line:sub(1,1) == "[" and line:sub(-1) == "]") then + if (line:sub(2,5) == "lfs ") then + section = nil -- skip LFS entries as there can be many and we never use them + else + section = line:sub(2,-2) + git_config[section] = git_config[section] or {} + end + elseif section then + local param, value = line:match('^%s-([%w|_]+)%s-=%s+(.+)$') + if (param and value ~= nil) then + git_config[section][param] = value + end + end + end + file:close() + + local remote_to_push = get_git_config_value('branch "'..branch..'"', 'remote') or '' + local remote_ref = get_git_config_value('remote "'..remote_to_push..'"', 'push') or + get_git_config_value('push', 'default') + + local text = remote_to_push + if remote_ref then text = text..'/'..remote_ref end + + return text ~= '' and text or nil end --- @@ -394,7 +476,7 @@ end -- Get the status and conflict status of working dir -- @return {bool , bool } --- -local function get_git_status() +local function get_git_status(git_dir) local file = io_popenyield("git --no-optional-locks status --porcelain 2>nul") if not file then return {} @@ -416,7 +498,10 @@ local function get_git_status() end file:close() - return { status = is_status, conflict = conflict_found } + local branch = get_git_branch(git_dir, false--[[fast]]) + local remote = get_git_remote(git_dir, branch) + + return { status = is_status, branch = branch, remote = remote, conflict = conflict_found } end --- @@ -515,11 +600,11 @@ end -- Use a prompt coroutine to get git status in the background. -- Cache the info so we can reuse it next time to reduce flicker. --- -local function get_git_info_table() +local function get_git_info_table(git_dir) local info = clink_promptcoroutine(function () -- Use git status if allowed. local cmderGitStatusOptIn = get_git_status_setting() - return cmderGitStatusOptIn and get_git_status() or {} + return cmderGitStatusOptIn and get_git_status(git_dir) or {} end) if not info then info = cached_info.git_info or {} @@ -539,10 +624,11 @@ local function git_prompt_filter() local git_dir = get_git_dir() local color if git_dir then - local branch = get_git_branch(git_dir) + local branch = get_git_branch(git_dir, true--[[fast]]) if branch then -- If in a different repo or branch than last time, discard cached info. - if cached_info.git_dir ~= git_dir or cached_info.git_branch ~= branch then + if cached_info.git_dir ~= git_dir or + (branch ~= ".invalid" and cached_info.git_branch ~= branch) then cached_info.git_info = nil cached_info.git_dir = git_dir cached_info.git_branch = branch @@ -550,10 +636,22 @@ local function git_prompt_filter() -- If we're inside of git repo then try to detect current branch -- Has branch => therefore it is a git folder, now figure out status - local gitInfo = get_git_info_table() + local gitInfo = get_git_info_table(git_dir) local gitStatus = gitInfo.status local gitConflict = gitInfo.conflict + -- Compensate for git reftables. + branch = gitInfo.branch or branch + if branch == ".invalid" then + branch = "Loading..." + elseif gitInfo.remote then + branch = branch.." -> "..gitInfo.remote + end + + -- Prevent an older clink-completions git_prompt.lua scripts from + -- modifying the prompt. + branch = "\x1b[10m"..branch + if gitStatus == nil then color = get_unknown_color() elseif gitStatus then