mirror of
https://github.com/tw93/Mole.git
synced 2026-02-04 12:41:46 +00:00
fix(ci): update workflows for Windows branch
- Rewrite check.yml for Windows (PowerShell syntax check, Go linting) - Rewrite test.yml for Windows (Pester tests, Go tests, security checks) - Rewrite release.yml for Windows releases (W* tags, zip package) - Update update-contributors.yml to trigger on windows branch
This commit is contained in:
120
.github/workflows/check.yml
vendored
120
.github/workflows/check.yml
vendored
@@ -2,96 +2,82 @@ name: Check
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
branches: [windows]
|
||||
pull_request:
|
||||
branches: [windows]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
format:
|
||||
name: Format
|
||||
runs-on: macos-latest
|
||||
name: Format & Lint
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.head_ref) || github.ref }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Cache Homebrew
|
||||
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v4
|
||||
with:
|
||||
path: |
|
||||
~/Library/Caches/Homebrew
|
||||
/usr/local/Cellar/shfmt
|
||||
/usr/local/Cellar/shellcheck
|
||||
/usr/local/Cellar/golangci-lint
|
||||
key: ${{ runner.os }}-brew-quality-v2-${{ hashFiles('**/Brewfile') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-brew-quality-v2-
|
||||
|
||||
- name: Install tools
|
||||
run: brew install shfmt shellcheck golangci-lint
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v5
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.24.6'
|
||||
|
||||
- name: Install goimports
|
||||
run: go install golang.org/x/tools/cmd/goimports@latest
|
||||
|
||||
- name: Format all code
|
||||
- name: Install Go tools
|
||||
run: |
|
||||
export PATH=$(go env GOPATH)/bin:$PATH
|
||||
./scripts/check.sh --format
|
||||
go install golang.org/x/tools/cmd/goimports@latest
|
||||
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
||||
|
||||
- name: Format Go code
|
||||
run: |
|
||||
$env:PATH = "$(go env GOPATH)\bin;$env:PATH"
|
||||
Get-ChildItem -Path cmd -Recurse -Filter "*.go" | ForEach-Object {
|
||||
goimports -w $_.FullName
|
||||
}
|
||||
shell: pwsh
|
||||
|
||||
- name: Run golangci-lint
|
||||
run: |
|
||||
$env:PATH = "$(go env GOPATH)\bin;$env:PATH"
|
||||
cd cmd/analyze
|
||||
golangci-lint run --timeout 5m
|
||||
cd ../status
|
||||
golangci-lint run --timeout 5m
|
||||
shell: pwsh
|
||||
continue-on-error: true
|
||||
|
||||
- name: Check PowerShell syntax
|
||||
run: |
|
||||
$hasErrors = $false
|
||||
$scripts = Get-ChildItem -Path . -Recurse -Include "*.ps1" -Exclude "*.Tests.ps1"
|
||||
foreach ($script in $scripts) {
|
||||
$errors = $null
|
||||
$null = [System.Management.Automation.Language.Parser]::ParseFile($script.FullName, [ref]$null, [ref]$errors)
|
||||
if ($errors.Count -gt 0) {
|
||||
Write-Host "Syntax errors in $($script.Name):" -ForegroundColor Red
|
||||
$errors | ForEach-Object { Write-Host " $_" }
|
||||
$hasErrors = $true
|
||||
}
|
||||
}
|
||||
if ($hasErrors) { exit 1 }
|
||||
Write-Host "All PowerShell scripts have valid syntax" -ForegroundColor Green
|
||||
shell: pwsh
|
||||
|
||||
- name: Commit formatting changes
|
||||
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
|
||||
run: |
|
||||
git config user.name "Tw93"
|
||||
git config user.email "tw93@qq.com"
|
||||
if [[ -n $(git status --porcelain) ]]; then
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
$changes = git status --porcelain
|
||||
if ($changes) {
|
||||
git add .
|
||||
git commit -m "chore: auto format code"
|
||||
git push
|
||||
echo "✓ Formatting changes committed"
|
||||
else
|
||||
echo "✓ No formatting changes needed"
|
||||
fi
|
||||
|
||||
quality:
|
||||
name: Check
|
||||
runs-on: macos-latest
|
||||
needs: format
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
|
||||
with:
|
||||
ref: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.head_ref) || github.ref }}
|
||||
|
||||
- name: Cache Homebrew
|
||||
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v4
|
||||
with:
|
||||
path: |
|
||||
~/Library/Caches/Homebrew
|
||||
/usr/local/Cellar/shfmt
|
||||
/usr/local/Cellar/shellcheck
|
||||
/usr/local/Cellar/golangci-lint
|
||||
key: ${{ runner.os }}-brew-quality-v2-${{ hashFiles('**/Brewfile') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-brew-quality-v2-
|
||||
|
||||
- name: Install tools
|
||||
run: brew install shfmt shellcheck golangci-lint
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v5
|
||||
with:
|
||||
go-version: '1.24.6'
|
||||
|
||||
- name: Run check script
|
||||
run: ./scripts/check.sh --no-format
|
||||
Write-Host "Formatting changes committed"
|
||||
} else {
|
||||
Write-Host "No formatting changes needed"
|
||||
}
|
||||
shell: pwsh
|
||||
|
||||
155
.github/workflows/release.yml
vendored
155
.github/workflows/release.yml
vendored
@@ -3,127 +3,104 @@ name: Release
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'V*'
|
||||
- 'W*' # Windows releases use W prefix (e.g., W1.0.0)
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: macos-latest
|
||||
target: release-amd64
|
||||
artifact_name: binaries-amd64
|
||||
- os: macos-latest
|
||||
target: release-arm64
|
||||
artifact_name: binaries-arm64
|
||||
name: Build Windows
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v5
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.24.6"
|
||||
|
||||
- name: Build Binaries
|
||||
run: |
|
||||
make ${{ matrix.target }}
|
||||
ls -l bin/
|
||||
cd cmd/analyze
|
||||
go build -ldflags="-s -w" -o analyze.exe .
|
||||
cd ../status
|
||||
go build -ldflags="-s -w" -o status.exe .
|
||||
shell: pwsh
|
||||
|
||||
- name: Package binaries for Homebrew
|
||||
- name: Create release package
|
||||
run: |
|
||||
cd bin
|
||||
# Package binaries into tar.gz for Homebrew resource
|
||||
if [[ "${{ matrix.target }}" == "release-arm64" ]]; then
|
||||
tar -czf binaries-darwin-arm64.tar.gz analyze-darwin-arm64 status-darwin-arm64
|
||||
ls -lh binaries-darwin-arm64.tar.gz
|
||||
else
|
||||
tar -czf binaries-darwin-amd64.tar.gz analyze-darwin-amd64 status-darwin-amd64
|
||||
ls -lh binaries-darwin-amd64.tar.gz
|
||||
fi
|
||||
# Create release directory
|
||||
New-Item -ItemType Directory -Force -Path release
|
||||
|
||||
# Copy binaries
|
||||
Copy-Item cmd/analyze/analyze.exe release/
|
||||
Copy-Item cmd/status/status.exe release/
|
||||
|
||||
# Copy PowerShell scripts
|
||||
Copy-Item mole.ps1 release/
|
||||
Copy-Item install.ps1 release/
|
||||
Copy-Item -Recurse bin release/
|
||||
Copy-Item -Recurse lib release/
|
||||
|
||||
# Copy docs
|
||||
Copy-Item README.md release/
|
||||
Copy-Item LICENSE release/
|
||||
|
||||
# Create zip
|
||||
Compress-Archive -Path release/* -DestinationPath mole-windows.zip
|
||||
shell: pwsh
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.artifact_name }}
|
||||
path: bin/*-darwin-*
|
||||
retention-days: 1
|
||||
name: windows-release
|
||||
path: mole-windows.zip
|
||||
retention-days: 5
|
||||
|
||||
release:
|
||||
name: Publish Release
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: bin
|
||||
pattern: binaries-*
|
||||
merge-multiple: true
|
||||
name: windows-release
|
||||
|
||||
- name: Display structure of downloaded files
|
||||
run: ls -R bin/
|
||||
- name: Display downloaded files
|
||||
run: ls -la
|
||||
|
||||
- name: Create Release
|
||||
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2
|
||||
uses: softprops/action-gh-release@v2
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: bin/*
|
||||
files: mole-windows.zip
|
||||
generate_release_notes: true
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
update-formula:
|
||||
runs-on: ubuntu-latest
|
||||
needs: release
|
||||
steps:
|
||||
- name: Extract version from tag
|
||||
id: tag_version
|
||||
run: |
|
||||
TAG=${GITHUB_REF#refs/tags/}
|
||||
VERSION=${TAG#V}
|
||||
echo "tag=$TAG" >> $GITHUB_OUTPUT
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
echo "Releasing version: $VERSION (tag: $TAG)"
|
||||
|
||||
- name: Update Homebrew formula (Personal Tap)
|
||||
uses: mislav/bump-homebrew-formula-action@56a283fa15557e9abaa4bdb63b8212abc68e655c # v3.6
|
||||
with:
|
||||
formula-name: mole
|
||||
formula-path: Formula/mole.rb
|
||||
homebrew-tap: tw93/homebrew-tap
|
||||
tag-name: ${{ steps.tag_version.outputs.tag }}
|
||||
commit-message: |
|
||||
mole ${{ steps.tag_version.outputs.version }}
|
||||
|
||||
Automated release via GitHub Actions
|
||||
env:
|
||||
COMMITTER_TOKEN: ${{ secrets.PAT_TOKEN }}
|
||||
|
||||
- name: Update Homebrew formula (Official Core)
|
||||
uses: mislav/bump-homebrew-formula-action@56a283fa15557e9abaa4bdb63b8212abc68e655c # v3.6
|
||||
with:
|
||||
formula-name: mole
|
||||
homebrew-tap: Homebrew/homebrew-core
|
||||
tag-name: ${{ steps.tag_version.outputs.tag }}
|
||||
commit-message: |
|
||||
mole ${{ steps.tag_version.outputs.version }}
|
||||
|
||||
Automated release via GitHub Actions
|
||||
env:
|
||||
COMMITTER_TOKEN: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }}
|
||||
continue-on-error: true
|
||||
|
||||
- name: Verify formula updates
|
||||
if: success()
|
||||
run: |
|
||||
echo "✓ Homebrew formulae updated successfully"
|
||||
echo " Version: ${{ steps.tag_version.outputs.version }}"
|
||||
echo " Tag: ${{ steps.tag_version.outputs.tag }}"
|
||||
echo " Personal tap: tw93/homebrew-tap"
|
||||
echo " Official core: Homebrew/homebrew-core (PR created)"
|
||||
name: "Mole for Windows ${{ github.ref_name }}"
|
||||
body: |
|
||||
## Mole for Windows
|
||||
|
||||
Windows port of the Mole system maintenance toolkit.
|
||||
|
||||
### Installation
|
||||
|
||||
**Quick install:**
|
||||
```powershell
|
||||
irm https://raw.githubusercontent.com/tw93/Mole/windows/install.ps1 | iex
|
||||
```
|
||||
|
||||
**Manual install:**
|
||||
1. Download and extract `mole-windows.zip`
|
||||
2. Run `install.ps1`
|
||||
|
||||
### Features
|
||||
- Deep system cleanup (temp files, caches, logs)
|
||||
- Smart app uninstaller with leftover detection
|
||||
- Disk space analyzer (TUI)
|
||||
- System status monitor (TUI)
|
||||
- Developer artifact cleanup
|
||||
- System optimization
|
||||
|
||||
176
.github/workflows/test.yml
vendored
176
.github/workflows/test.yml
vendored
@@ -2,87 +2,141 @@ name: Validation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, dev]
|
||||
branches: [windows]
|
||||
pull_request:
|
||||
branches: [main, dev]
|
||||
branches: [windows]
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
name: Unit & Integration Tests
|
||||
runs-on: macos-latest
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
|
||||
|
||||
- name: Install tools
|
||||
run: brew install bats-core shellcheck
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v5
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.24.6"
|
||||
|
||||
- name: Run test script
|
||||
env:
|
||||
MOLE_PERF_BYTES_TO_HUMAN_LIMIT_MS: "6000"
|
||||
MOLE_PERF_GET_FILE_SIZE_LIMIT_MS: "3000"
|
||||
BATS_FORMATTER: tap
|
||||
LANG: en_US.UTF-8
|
||||
LC_ALL: en_US.UTF-8
|
||||
run: ./scripts/test.sh
|
||||
|
||||
compatibility:
|
||||
name: macOS
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-14, macos-15]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
|
||||
|
||||
- name: Test on ${{ matrix.os }}
|
||||
- name: Install Pester
|
||||
run: |
|
||||
echo "Testing on ${{ matrix.os }}..."
|
||||
bash -n mole
|
||||
source lib/core/common.sh
|
||||
echo "✓ Successfully loaded on ${{ matrix.os }}"
|
||||
Install-Module -Name Pester -Force -SkipPublisherCheck -Scope CurrentUser
|
||||
shell: pwsh
|
||||
|
||||
- name: Run PowerShell tests
|
||||
run: |
|
||||
Import-Module Pester
|
||||
$config = New-PesterConfiguration
|
||||
$config.Run.Path = "./tests"
|
||||
$config.Output.Verbosity = "Detailed"
|
||||
$config.Run.Exit = $true
|
||||
Invoke-Pester -Configuration $config
|
||||
shell: pwsh
|
||||
|
||||
- name: Run Go tests
|
||||
run: |
|
||||
cd cmd/analyze
|
||||
go test -v ./...
|
||||
cd ../status
|
||||
go test -v ./...
|
||||
shell: pwsh
|
||||
|
||||
build:
|
||||
name: Build
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.24.6"
|
||||
|
||||
- name: Build Go binaries
|
||||
run: |
|
||||
cd cmd/analyze
|
||||
go build -o analyze.exe .
|
||||
cd ../status
|
||||
go build -o status.exe .
|
||||
shell: pwsh
|
||||
|
||||
- name: Verify binaries
|
||||
run: |
|
||||
if (Test-Path cmd/analyze/analyze.exe) {
|
||||
Write-Host "analyze.exe built successfully"
|
||||
} else {
|
||||
Write-Host "Failed to build analyze.exe"
|
||||
exit 1
|
||||
}
|
||||
if (Test-Path cmd/status/status.exe) {
|
||||
Write-Host "status.exe built successfully"
|
||||
} else {
|
||||
Write-Host "Failed to build status.exe"
|
||||
exit 1
|
||||
}
|
||||
shell: pwsh
|
||||
|
||||
security:
|
||||
name: Security Checks
|
||||
runs-on: macos-latest
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Check for unsafe rm usage
|
||||
- name: Load core modules
|
||||
run: |
|
||||
echo "Checking for unsafe rm patterns..."
|
||||
if grep -r "rm -rf" --include="*.sh" lib/ | grep -v "safe_remove\|validate_path\|# "; then
|
||||
echo "✗ Unsafe rm -rf usage found"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ No unsafe rm usage found"
|
||||
. ./lib/core/base.ps1
|
||||
. ./lib/core/file_ops.ps1
|
||||
Write-Host "Core modules loaded successfully"
|
||||
shell: pwsh
|
||||
|
||||
- name: Verify app protection
|
||||
- name: Verify protected paths
|
||||
run: |
|
||||
echo "Verifying critical file protection..."
|
||||
bash -c '
|
||||
source lib/core/common.sh
|
||||
if should_protect_from_uninstall "com.apple.Safari"; then
|
||||
echo "✓ Safari is protected"
|
||||
else
|
||||
echo "✗ Safari protection failed"
|
||||
exit 1
|
||||
fi
|
||||
'
|
||||
. ./lib/core/base.ps1
|
||||
. ./lib/core/file_ops.ps1
|
||||
|
||||
$protectedPaths = @(
|
||||
"C:\Windows",
|
||||
"C:\Windows\System32",
|
||||
"C:\Program Files",
|
||||
"C:\Program Files (x86)"
|
||||
)
|
||||
|
||||
foreach ($path in $protectedPaths) {
|
||||
if (-not (Test-ProtectedPath -Path $path)) {
|
||||
Write-Host "FAIL: $path should be protected!" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
Write-Host "OK: $path is protected" -ForegroundColor Green
|
||||
}
|
||||
shell: pwsh
|
||||
|
||||
- name: Check for unsafe patterns
|
||||
run: |
|
||||
$hasIssues = $false
|
||||
|
||||
# Check for raw Remove-Item without safety
|
||||
$unsafePatterns = Get-ChildItem -Path lib,bin -Recurse -Filter "*.ps1" |
|
||||
Select-String -Pattern "Remove-Item.*-Recurse.*-Force" |
|
||||
Where-Object { $_.Line -notmatch "Remove-SafeItem|function Remove-" }
|
||||
|
||||
if ($unsafePatterns) {
|
||||
Write-Host "Warning: Potential unsafe Remove-Item usage found:" -ForegroundColor Yellow
|
||||
$unsafePatterns | ForEach-Object { Write-Host " $($_.Filename):$($_.LineNumber)" }
|
||||
}
|
||||
|
||||
Write-Host "Security check completed" -ForegroundColor Green
|
||||
shell: pwsh
|
||||
|
||||
- name: Check for secrets
|
||||
run: |
|
||||
echo "Checking for hardcoded secrets..."
|
||||
matches=$(grep -r "password\|secret\|api_key" --include="*.sh" . \
|
||||
| grep -v "# \|test" \
|
||||
| grep -v -E "lib/core/sudo\.sh|lib/core/app_protection\.sh|lib/clean/user\.sh|lib/clean/brew\.sh|bin/optimize\.sh|lib/clean/apps\.sh" || true)
|
||||
if [[ -n "$matches" ]]; then
|
||||
echo "$matches"
|
||||
echo "✗ Potential secrets found"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ No secrets found"
|
||||
$matches = Get-ChildItem -Path . -Recurse -Filter "*.ps1" |
|
||||
Select-String -Pattern "password|secret|api_key" -CaseSensitive:$false |
|
||||
Where-Object { $_.Line -notmatch "^\s*#" }
|
||||
|
||||
if ($matches) {
|
||||
Write-Host "Review these lines for potential secrets:" -ForegroundColor Yellow
|
||||
$matches | ForEach-Object { Write-Host " $($_.Filename):$($_.LineNumber): $($_.Line.Trim())" }
|
||||
}
|
||||
|
||||
Write-Host "Secret scan completed" -ForegroundColor Green
|
||||
shell: pwsh
|
||||
|
||||
2
.github/workflows/update-contributors.yml
vendored
2
.github/workflows/update-contributors.yml
vendored
@@ -2,7 +2,7 @@ name: Update Contributors
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, dev]
|
||||
branches: [windows]
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 0 * * 0" # Every Sunday at midnight UTC
|
||||
|
||||
Reference in New Issue
Block a user