Skip to content
Draft
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
19 changes: 19 additions & 0 deletions .github/workflows/test-zizmor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: test-zizmor

on:
merge_group:
pull_request:
branches:
- main

jobs:
test-zizmor-action:
runs-on: ubuntu-latest
steps:
- name: Checkout repo (needed to reference local action)
uses: actions/[email protected]
with:
persist-credentials: false

- name: test-zizmor-action
uses: ./actions/zizmor-audit
1 change: 1 addition & 0 deletions actions/zizmor-audit/.tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodejs 23.10.0
3 changes: 3 additions & 0 deletions actions/zizmor-audit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# zizmor-audit

> Run zizmor audit
74 changes: 74 additions & 0 deletions actions/zizmor-audit/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: zizmor-audit
description: "Run zizmor audit"

inputs:
zizmor-version:
description: "Version of zizmor to install. Defauts to 1.5.1."
required: false
default: "1.5.1"

zizmor-min-severity:
description: |
Minimum severity to report. Defaults to high.
Possible options:
- unknown
- informational
- low
- medium
- high
required: false
default: "high"

workflows-path:
description: "Path to the workflows to audit."
required: false
default: ".github/workflows/"

runs:
using: composite
steps:
# - name: Install zizmor
# shell: bash
# env:
# VERSION: ${{ inputs.zizmor-version }}
# run: cargo install --quiet --locked zizmor --version ${VERSION}

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.x"

- name: Install Zizmor from PyPI
shell: bash
env:
VERSION: ${{ inputs.zizmor-version }}
run: |
pip install zizmor==${VERSION}

- name: Debug
shell: bash
run: |
ls -la ${{ github.action_path }}

- name: Setup nodejs
uses: smartcontractkit/.github/actions/setup-nodejs@main
with:
node-version-file: ./actions/zizmor-audit/.tool-versions
pnpm-version: "^10.0.0"
package-json-directory: ./actions/zizmor-audit

# - name: Run Zizmor
# shell: bash
env:
MIN_SEVERITY: ${{ inputs.zizmor-min-severity }}
WORKFLOWS_PATH: ${{ inputs.workflows-path }}
# run: |
# zizmor ${WORKFLOWS_PATH} --min-severity ${MIN_SEVERITY} --quiet --format json

- name: Run action
shell: bash
env:
MIN_SEVERITY: ${{ inputs.zizmor-min-severity }}
WORKFLOWS_PATH: ${{ inputs.workflows-path }}
run: |
node ${GITHUB_ACTION_PATH}/annotate.mts ${WORKFLOWS_PATH} ${MIN_SEVERITY}
113 changes: 113 additions & 0 deletions actions/zizmor-audit/annotate.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/usr/bin/env node

import * as core from "@actions/core";
import { execSync } from "child_process";
import { existsSync } from "fs";
import { join } from "path";
import { cwd } from "process";
import { start } from "repl";

function processCLIInputs() {
const [path, minSeverity] = process.argv.slice(2);

if (!path || !minSeverity) {
core.error("Usage: node annotate.mts <path> <minSeverity>");
process.exit(1);
}

if (!["low", "medium", "high", "informational", "unknown"].includes(minSeverity)) {
core.error("minSeverity must be one of low, medium, high, informational, unknown");
process.exit(1);
}

if (!existsSync(path)) {
core.error(`Path (${path}) does not exist.`);
process.exit(1);
}

return [path, minSeverity];
}

function main() {
core.info("Running Zizmor audit...");

const [path, minSeverity] = processCLIInputs();

const zizStdOut = execSync(`zizmor ${path} --min-severity=${minSeverity} --quiet --format=json --no-exit-codes`, { encoding: "utf-8" }).trim();

const zizEntries = JSON.parse(zizStdOut) as ZizmorEntry[];

for (const zEntry of zizEntries) {
if (zEntry.ignored) {
core.info(`Ignored: ${zEntry.ident}`);
continue;
}

const location = zEntry.locations[zEntry.locations.length - 1];

const workflowPath = join(cwd(), location.symbolic.key.Local.given_path);
const annotationProperties = {
title: zEntry.ident,
file: workflowPath,
startLine: location.concrete.location.start_point.row,
endLine: location.concrete.location.end_point.row,
}
core.error(`Zizmor violation: ${zEntry.desc} - ${zEntry.url}\n${location.symbolic.annotation}`, { ...annotationProperties });
}
}

main();


interface ZizmorEntry {
ident: string;
desc: string;
url: string;
determinations: {
confidence: string;
severity: string;
persona: string;
},
locations: ZizmorLocation[];
ignored: boolean;
}

interface ZizmorLocation {
symbolic: ZizmorLocationSymbolic;
concrete: ZizmorLocationConcrete;

}


interface ZizmorLocationSymbolic {
key: {
Local: {
prefix: string;
given_path: string;
}
};
annotation: string;
route: {
components: { Key: string }[];
}
primary: boolean;
}

interface ZizmorLocationConcrete {
location: {
start_point: {
row: number;
column: number;
},
end_point: {
row: number;
column: number;
},
offset_span: {
start: number;
end: number;
}
};
feature: string;
comments: string[];
}
14 changes: 14 additions & 0 deletions actions/zizmor-audit/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "zizmor-audit",
"version": "0.0.0",
"description": "",
"private": true,
"scripts": {},
"author": "@smartcontractkit",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.10.1",
"tsx": "^4.16.2"
},
"repository": "https://github.com/smartcontractkit/.github"
}
7 changes: 7 additions & 0 deletions actions/zizmor-audit/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "zizmor-audit",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"sourceRoot": "actions/zizmor-audit",
"targets": {}
}
10 changes: 10 additions & 0 deletions actions/zizmor-audit/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"noEmit": true, // Optional - see note below
"target": "esnext",
"module": "nodenext",
"rewriteRelativeImportExtensions": true,
"erasableSyntaxOnly": true,
"verbatimModuleSyntax": true
}
}
Loading
Loading