Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
3d1755a
Update test-pytest.yml
JamesonRGrieve Jun 4, 2025
00a073a
Update test-pytest.yml
JamesonRGrieve Jun 4, 2025
18c9120
Update test-pytest.yml
JamesonRGrieve Jun 4, 2025
a760433
Update test-pytest.yml
JamesonRGrieve Jun 4, 2025
820063a
Silent;
JamesonRGrieve Jun 4, 2025
3ba8bc6
Silent;
JamesonRGrieve Jun 4, 2025
ac1a105
Quiet;
JamesonRGrieve Jun 4, 2025
e585ed7
Quieter;
JamesonRGrieve Jun 4, 2025
e2d8258
Remove old pytest workflow; Add usage;
JamesonRGrieve Jun 11, 2025
c231dc2
Revert pytest;
JamesonRGrieve Jun 11, 2025
4ce4de3
Update regression script;
JamesonRGrieve Jun 11, 2025
97bb781
Update regression script;
JamesonRGrieve Jun 11, 2025
e72ad09
Update regression script;
JamesonRGrieve Jun 11, 2025
1234323
Update regression script;
JamesonRGrieve Jun 11, 2025
eda5d63
Update regression script;
JamesonRGrieve Jun 11, 2025
86bb996
Update regression script;
JamesonRGrieve Jun 11, 2025
3f35bb3
Update regression script with pass-to-gone and fail-to-gone;
JamesonRGrieve Jun 11, 2025
051f154
Update regression script with pass-to-gone and fail-to-gone;
JamesonRGrieve Jun 11, 2025
32bbe0a
Fix dupe artifacts;
JamesonRGrieve Jun 11, 2025
2b4dd80
Fix dupe artifacts;
JamesonRGrieve Jun 11, 2025
3999586
Fix Discord;
JamesonRGrieve Jun 11, 2025
69eeca1
Hopefully fix gone tests;
JamesonRGrieve Jun 12, 2025
32c0124
Fix passing tests;
JamesonRGrieve Jun 12, 2025
a9c30f8
Fix passing tests;
JamesonRGrieve Jun 12, 2025
76d5153
Discord file upload - maybe;
JamesonRGrieve Jun 12, 2025
46e199a
Fix count; Maybe fix files;
JamesonRGrieve Jun 12, 2025
f2bd92b
Update build-next.yml
austinleblanc Jun 16, 2025
40351c0
Update build-next.yml
austinleblanc Jun 16, 2025
4f01d0e
modified workflows
parull249 Jun 30, 2025
668a8f9
added scripts
parull249 Jun 30, 2025
b6c4be9
added bandit reusable code and trigger
parull249 Jul 1, 2025
bcb6175
modified gh-projects-qa.yml
parull249 Jul 1, 2025
a73f62e
updated test-ts-lint.yml
parull249 Jul 2, 2025
0e9e081
updated test-ts-lint.yml
parull249 Jul 2, 2025
a9c2e0c
updated test-lint-py.yml
parull249 Jul 2, 2025
ff75c46
updated test-lint-py.yml
parull249 Jul 2, 2025
e0bb1ff
updated test-lint-py.yml
parull249 Jul 2, 2025
623fa3c
modified permissions in on-pr-dev.yml
parull249 Jul 3, 2025
606ab19
Blocked Issues and Tracking Date (#2)
parull249 Jul 14, 2025
b723243
Merge branch 'main' into dev-fix-2
parull249 Jul 17, 2025
5f136f6
adjust severity filtering for Bandit to only include HIGH severity is…
parull249 Aug 7, 2025
16a1847
resolved conflicts
parull249 Aug 8, 2025
29b0b10
resolved conflicts
parull249 Aug 8, 2025
c63ac30
resolved conflicts
parull249 Aug 8, 2025
d5c91f0
resolved conflicts
parull249 Aug 8, 2025
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
4 changes: 2 additions & 2 deletions .github/workflows/build-next.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ on:
default: "ubuntu-latest"
jobs:
lint:
uses: ./.github/workflows/test-lint-py.yml
uses: ./.github/workflows/test-py-lint.yml
permissions:
contents: write

Expand Down Expand Up @@ -51,6 +51,6 @@ jobs:
node-version: ${{ inputs.node-version }}
- run: |
npm i lightningcss-linux-x64-gnu @tailwindcss/oxide-linux-x64-gnu sass-embedded-linux-x64
npm ci
npm i
npm list zod --depth=0
npm run build
3 changes: 0 additions & 3 deletions .github/workflows/gh-projects-qa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ name: Reusable - Set Q/A Status in Zephyrex Board

on:
workflow_call:
secrets:
GITHUB_TOKEN:
required: true

jobs:
qa-update-status:
Expand Down
87 changes: 87 additions & 0 deletions .github/workflows/issue-blocker-reusuable.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# .github/workflows/issue-blocker.yml

name: "Reusable Issue Blocker Workflow"

on:
workflow_dispatch:
workflow_call:

permissions:
issues: write

jobs:
clean-blocked-comments:
runs-on: ubuntu-latest
steps:
- name: Clean up 'Blocked by' references and manage issue status
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const regex = /#(\d+)/g;

const issues = await github.rest.issues.listForRepo({ owner, repo, state: 'open' });

for (const issue of issues.data) {
if (issue.pull_request) continue;

console.log(`\n🔍 Issue #${issue.number}: ${issue.title}`);

const comments = await github.rest.issues.listComments({ owner, repo, issue_number: issue.number });
let updated = false;

for (const comment of comments.data) {
if (!comment.body.toLowerCase().includes('blocked by')) continue;

console.log(`💬 Comment ID: ${comment.id}`);
console.log(`📄 Raw: ${JSON.stringify(comment.body)}`);

const matches = [...comment.body.matchAll(regex)].map(m => parseInt(m[1]));
const stillOpen = [];

for (const ref of matches) {
try {
const refIssue = await github.rest.issues.get({ owner, repo, issue_number: ref });
if (refIssue.data.state === 'open') {
console.log(`🔗 Found reference to issue #${ref}\n⏳ Issue #${ref} is still open.`);
stillOpen.push(`#${ref}`);
} else {
console.log(`🔗 Found reference to issue #${ref}\n✅ Issue #${ref} is closed.`);
}
} catch (err) {
console.warn(`⚠️ Issue #${ref} could not be fetched.`);
}
}

const newBody = stillOpen.length > 0
? `Blocked by ${stillOpen.join(' ')}`
: '[Auto-removed blocked-by reference: all blocking issues closed.]';

if (comment.body !== newBody) {
await github.rest.issues.updateComment({
owner,
repo,
comment_id: comment.id,
body: newBody
});
updated = true;
console.log(`✏️ Comment updated to: "${newBody}"`);
} else {
console.log(`✅ Comment is already correct. No update needed.`);
}
}

// Manage issue status using labels
const labels = issue.labels.map(l => l.name);
const hasBlocked = comments.data.some(c => c.body.includes('Blocked by #') && !c.body.includes('Auto-removed'));

if (hasBlocked && !labels.includes('Blocked')) {
await github.rest.issues.addLabels({ owner, repo, issue_number: issue.number, labels: ['Blocked'] });
console.log(`🏷️ Label 'Blocked' added.`);
} else if (!hasBlocked && labels.includes('Blocked')) {
await github.rest.issues.setLabels({ owner, repo, issue_number: issue.number, labels: ['To-Do'] });
console.log(`🚫 Label 'To-Do' added.`);
}
}
34 changes: 9 additions & 25 deletions .github/workflows/meta-regression-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,6 @@ jobs:
ITEM_TYPE_SINGULAR_ENV: "${{ inputs.item_type_singular }}"
ITEM_TYPE_PLURAL_ENV: "${{ inputs.item_type_plural }}"
run: |
# Create debug file for detailed output
exec 3>&1 4>&2
exec 1> >(tee -a debug_regression_analysis.log) 2>&1

echo "Running regression analysis..."

python3 - <<'EOF'
Expand Down Expand Up @@ -159,9 +155,11 @@ jobs:
regression_items_list = sorted(list(target_passing_set.intersection(pr_failing_set)))

if regression_items_list:
print(f"Found {len(regression_items_list)} regression(s)!")
has_regressions_output = "true"
regression_count_output = len(regression_items_list)
print(f"Found {len(regression_items_list)} regression(s)!")
print("::error::Test Regressions Found!")
print(f"::error::{len(regression_items_list)} regression(s) detected. This job was intentionally failed.")
with open("regression_details.txt", "w") as f:
f.write(f"Found {len(regression_items_list)} {item_type_p} that were passing/clean in the target branch but are now failing/have issues in the PR branch:\n\n")
for idx, item in enumerate(regression_items_list, 1):
Expand Down Expand Up @@ -190,12 +188,9 @@ jobs:
print("::warning::GITHUB_OUTPUT environment variable not set.")
EOF

# Restore stdout/stderr for GitHub Actions
exec 1>&3 2>&4

echo "Regression analysis script completed."

# Only show regression summary in logs if regressions found
# Show regression summary in logs if regressions found
if [ -f "regression_details.txt" ]; then
REGRESSION_COUNT=$(grep -c "^[0-9]\+\." regression_details.txt || echo "0")
if [ "$REGRESSION_COUNT" -gt 0 ]; then
Expand All @@ -205,30 +200,19 @@ jobs:
fi
fi

- name: Upload debug logs
- name: Upload regression analysis results
if: always()
uses: actions/upload-artifact@v4
with:
name: regression_analysis_debug_logs_${{ inputs.pr_number || inputs.run_id }}
path: debug_regression_analysis.log
retention-days: 7
name: regression_analysis_results_${{ inputs.pr_number || inputs.run_id }}
path: |
regression_details.txt
retention-days: 3
if-no-files-found: ignore

- name: Fail job if regressions are found
if: steps.check-regressions-script.outputs.HAS_REGRESSIONS == 'true'
run: |
echo "Regressions detected. Failing the job as per configuration."
REGRESSION_COUNT_VAL=${{ steps.check-regressions-script.outputs.REGRESSION_COUNT }}
echo "### :x: Regressions Found!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY # Newline
echo "**$REGRESSION_COUNT_VAL regression(s) detected.** This job was intentionally failed." >> $GITHUB_STEP_SUMMARY
echo "The 'Upload regression details artifact' step will still attempt to upload details." >> $GITHUB_STEP_SUMMARY
exit 1

- name: Upload regression details artifact
uses: actions/upload-artifact@v4
if: always()
with:
name: regression_details_pr_${{ inputs.pr_number || inputs.run_id }}_${{ inputs.item_type_plural }}
path: regression_details.txt
retention-days: 7
77 changes: 77 additions & 0 deletions .github/workflows/sync-meta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Reusable Workflow: Workflows/.github/workflows/sync-meta.yml

name: Reusable Metadata Sync

on:
workflow_call:
secrets:
PAT_TOKEN:
required: true
inputs:
sync_labels:
required: false
type: boolean
default: true
sync_templates:
required: false
type: boolean
default: true
sync_milestones:
required: false
type: boolean
default: true
sync_branch_rules:
required: false
type: boolean
default: true
runs_on:
required: false
type: string
default: "ubuntu-latest"

jobs:
sync:
runs-on: ${{ inputs.runs_on }}
steps:
- name: Checkout source repo (self)
uses: actions/checkout@v4
with:
repository: JamesonRGrieve/Workflows
token: ${{ secrets.PAT_TOKEN }}
path: source

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'

- name: Install dependencies
run: pip install requests PyGithub

- name: Sync Labels
if: ${{ inputs.sync_labels }}
run: |
python3 source/scripts/sync_labels.py
env:
PAT_TOKEN: ${{ secrets.PAT_TOKEN }}

- name: Sync Templates
if: ${{ inputs.sync_templates }}
run: |
python3 source/scripts/sync_templates.py
env:
PAT_TOKEN: ${{ secrets.PAT_TOKEN }}

- name: Sync Milestones
if: ${{ inputs.sync_milestones }}
run: |
python3 source/scripts/sync_milestones.py
env:
PAT_TOKEN: ${{ secrets.PAT_TOKEN }}

- name: Sync Branch Protection Rules
if: ${{ inputs.sync_branch_rules }}
run: |
python3 source/scripts/sync_branch_protection.py
env:
PAT_TOKEN: ${{ secrets.PAT_TOKEN }}
130 changes: 130 additions & 0 deletions .github/workflows/test-bandit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
name: Reusable Bandit Security Check with Regression Detection

# This reusable workflow is triggered by other workflows using 'workflow_call'
on:
workflow_call:
inputs:
target_branch_to_compare:
description: "Target branch to compare against (e.g., main)"
required: true
type: string
runs_on:
required: false
type: string
default: "ubuntu-latest"
outputs:
bandit_issues_json:
description: "JSON output of Bandit issues on PR branch"
value: ${{ jobs.run-bandit.outputs.bandit_issues_json }}

jobs:
# Job 1: Run Bandit on the PR branch
run-bandit:
name: Run Bandit on PR Branch & Extract Results
runs-on: ${{ inputs.runs_on }}
outputs:
bandit_issues_json: ${{ steps.extract-pr.outputs.BANDIT_JSON }}
steps:
# Step 1: Checkout the current pull request code
- name: Checkout PR Branch
uses: actions/checkout@v4.1.1
with:
persist-credentials: false

# Step 2: Set up Python 3.10 environment
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"

# Step 3: Install Bandit (Python security scanner)
- name: Install Bandit
run: pip install bandit

# Step 4: Run Bandit and output results to a file
- name: Run Bandit on PR Branch
run: |
bandit -r . -lll -f json -o pr_bandit_output.json || true

# Step 5: Upload the results as a GitHub Actions artifact (for debugging or reporting)
- name: Upload PR Artifact
uses: actions/upload-artifact@v4
with:
name: pr_bandit_output
path: pr_bandit_output.json

# Step 6: Extract the raw issue list from the Bandit JSON output
- name: Extract PR Bandit JSON
id: extract-pr
run: |
CONTENT=$(cat pr_bandit_output.json | jq -c '.results')
echo "BANDIT_JSON=$CONTENT" >> $GITHUB_OUTPUT

# Job 2: Run Bandit on the target branch for comparison
run-bandit-on-target:
name: Run Bandit on Target Branch
runs-on: ${{ inputs.runs_on }}
outputs:
bandit_target_json: ${{ steps.extract-target.outputs.TARGET_JSON }}
steps:
# Step 1: Checkout the base branch (e.g., main)
- name: Checkout Target Branch
uses: actions/checkout@v4
with:
ref: ${{ inputs.target_branch_to_compare }}
persist-credentials: false

# Step 2: Set up Python environment
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"

# Step 3: Install Bandit
- name: Install Bandit
run: pip install bandit

# Step 4: Run Bandit and save output
- name: Run Bandit on Target Branch
run: |
bandit -r . -lll -f json -o target_bandit_output.json || true

# Step 5: Upload results from the target branch
- name: Upload Target Artifact
uses: actions/upload-artifact@v4
with:
name: target_bandit_output
path: target_bandit_output.json

# Step 6: Extract raw issue list from the Bandit output
- name: Extract Target Bandit JSON
id: extract-target
run: |
CONTENT=$(cat target_bandit_output.json | jq -c '.results')
echo "TARGET_JSON=$CONTENT" >> $GITHUB_OUTPUT

# Job 3: Compare the PR results against the target to detect regressions
compare-bandit:
name: Compare Bandit Issues (Regression Analysis)
runs-on: ${{ inputs.runs_on }}
needs: [run-bandit, run-bandit-on-target]
steps:
- name: Compare JSON
run: |
echo "Comparing Bandit results between PR and target branch..."

echo "${{ needs.run-bandit.outputs.bandit_issues_json }}" > pr.json
echo "${{ needs.run-bandit-on-target.outputs.bandit_target_json }}" > target.json

# Compare both JSON lists to find issues present in PR but not in target
NEW_ISSUES=$(jq -n --argfile pr pr.json --argfile base target.json '
$pr - $base | length')

echo "New security issues introduced: $NEW_ISSUES"

if [ "$NEW_ISSUES" -gt 0 ]; then
echo "::error::New Bandit issues introduced in PR branch."
exit 1
else
echo "No new security issues introduced."
fi
Loading