Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/cmind-pre-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@ on:
paths:
- "CoderMind/**"
- ".github/workflows/cmind-pre-release.yml"
- ".github/workflows/cmind-security-tests.yml"
- ".github/workflows/scripts/cmind/**"
workflow_dispatch:

jobs:
security:
permissions:
contents: read
uses: ./.github/workflows/cmind-security-tests.yml
pre-release:
needs: security
runs-on: ubuntu-latest
permissions:
contents: write
Expand Down Expand Up @@ -40,8 +46,19 @@ jobs:

- name: Create release package variants
if: steps.check_release.outputs.exists == 'false'
env:
SCRIPTS: "sh ps"
run: .github/workflows/scripts/cmind/create-release-packages.sh "${{ steps.get_tag.outputs.new_version }}"

- uses: actions/setup-python@v5
if: steps.check_release.outputs.exists == 'false'
with:
python-version: "3.12"

- name: Verify all 22 freshly built publishing ZIPs
if: steps.check_release.outputs.exists == 'false'
run: python3 -I -B CoderMind/tests/verify_release_security.py CoderMind/.genreleases

- name: Generate release notes
if: steps.check_release.outputs.exists == 'false'
run: .github/workflows/scripts/cmind/generate-release-notes.sh "${{ steps.get_tag.outputs.new_version }}" "${{ steps.get_tag.outputs.latest_tag }}" pre
Expand Down
17 changes: 17 additions & 0 deletions .github/workflows/cmind-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@ on:
paths:
- "CoderMind/**"
- ".github/workflows/cmind-release.yml"
- ".github/workflows/cmind-security-tests.yml"
- ".github/workflows/scripts/cmind/**"
workflow_dispatch:

jobs:
security:
permissions:
contents: read
uses: ./.github/workflows/cmind-security-tests.yml
release:
needs: security
runs-on: ubuntu-latest
permissions:
contents: write
Expand Down Expand Up @@ -43,8 +49,19 @@ jobs:

- name: Create release package variants
if: steps.check_release.outputs.exists == 'false'
env:
SCRIPTS: "sh ps"
run: .github/workflows/scripts/cmind/create-release-packages.sh "${{ steps.get_tag.outputs.new_version }}"

- uses: actions/setup-python@v5
if: steps.check_release.outputs.exists == 'false'
with:
python-version: "3.12"

- name: Verify all 22 freshly built publishing ZIPs
if: steps.check_release.outputs.exists == 'false'
run: python3 -I -B CoderMind/tests/verify_release_security.py CoderMind/.genreleases

- name: Generate release notes
if: steps.check_release.outputs.exists == 'false'
run: .github/workflows/scripts/cmind/generate-release-notes.sh "${{ steps.get_tag.outputs.new_version }}" "${{ steps.get_tag.outputs.latest_tag }}" stable
Expand Down
59 changes: 59 additions & 0 deletions .github/workflows/cmind-security-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: CoderMind Security Regressions

on:
pull_request:
paths:
- "CoderMind/**"
- ".github/workflows/cmind-*.yml"
- ".github/workflows/scripts/cmind/**"
workflow_dispatch:
workflow_call:

permissions:
contents: read

jobs:
security-tests:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
timeout-minutes: 20
defaults:
run:
shell: pwsh
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Build and install wheel on disposable CI runner
run: |
python -m pip install build
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
python -m build --wheel CoderMind --outdir "$env:RUNNER_TEMP/wheels"
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
$wheel = @(Get-ChildItem "$env:RUNNER_TEMP/wheels" -Filter '*.whl')
if ($wheel.Count -ne 1) { throw 'Expected one wheel' }
python -m pip install $wheel[0].FullName
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
- name: Source policy and migration regressions (no real subprocesses)
run: python -I -B CoderMind/tests/run_security_tests.py
- name: Installed wheel regressions and source identity
run: python -I -B CoderMind/tests/run_security_tests.py --installed
- name: Inert execution regressions against installed wheel
run: python -I -B CoderMind/tests/run_security_tests.py --installed --integration
- name: Build sh and ps release ZIPs with Bash packager
if: runner.os == 'Linux'
shell: bash
env:
SCRIPTS: "sh ps"
run: bash .github/workflows/scripts/cmind/create-release-packages.sh v0.0.0-security-test
- name: Build sh and ps release ZIPs with PowerShell packager
if: runner.os == 'Windows'
run: ./.github/workflows/scripts/cmind/create-release-packages.ps1 -Version v0.0.0-security-test -Scripts 'sh ps'
- name: Verify all 22 release variants carry the reviewed Python scripts
run: python -I -B CoderMind/tests/verify_release_security.py CoderMind/.genreleases
11 changes: 6 additions & 5 deletions .github/workflows/scripts/cmind/create-release-packages.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -352,14 +352,15 @@ $AllAgents = @('copilot', 'claude', 'gemini', 'cursor-agent', 'qwen', 'opencode'
$AllScripts = @('sh', 'ps')

function Normalize-List {
param([string]$Input)
param([string]$Value)

if ([string]::IsNullOrEmpty($Input)) {
if ([string]::IsNullOrEmpty($Value)) {
return @()
}

# Split by comma or space and remove duplicates while preserving order
$items = $Input -split '[,\s]+' | Where-Object { $_ } | Select-Object -Unique
# Do not use $Input: it is PowerShell's automatic pipeline enumerator.
$items = $Value -split '[,\s]+' | Where-Object { $_ } | Select-Object -Unique
return $items
}

Expand All @@ -382,7 +383,7 @@ function Validate-Subset {

# Determine agent list
if (-not [string]::IsNullOrEmpty($Agents)) {
$AgentList = Normalize-List -Input $Agents
$AgentList = Normalize-List -Value $Agents
if (-not (Validate-Subset -Type 'agent' -Allowed $AllAgents -Items $AgentList)) {
exit 1
}
Expand All @@ -392,7 +393,7 @@ if (-not [string]::IsNullOrEmpty($Agents)) {

# Determine script list
if (-not [string]::IsNullOrEmpty($Scripts)) {
$ScriptList = Normalize-List -Input $Scripts
$ScriptList = Normalize-List -Value $Scripts
if (-not (Validate-Subset -Type 'script' -Allowed $AllScripts -Items $ScriptList)) {
exit 1
}
Expand Down
Loading
Loading