11 Commits
Author SHA1 Message Date
Dreaded_X 7be22cbace feat: Support gitea
Continuous integration / main (push) Successful in 1m22s
2026-08-26 05:02:32 +02:00
Dreaded_X 36a5751a64 fix: CI does not run on gitea
Continuous integration / main (push) Successful in 2m43s
2026-08-26 04:00:14 +02:00
Aaron Kelbsch c72c196d32 docs: update docs
Continuous integration / main (push) Failing after 41s
2026-08-26 03:55:14 +02:00
Aaron Kelbsch 50cb1867b0 feat: allow custom labels for new issues 2026-08-26 03:55:12 +02:00
Aaron Kelbsch 380200d383 docs: update readme 2026-08-26 03:55:11 +02:00
Aaron Kelbsch d18d2d8134 feat: also write issues when manually triggered 2026-08-26 03:55:10 +02:00
Aaron Kelbsch b7e98a4fa5 chore: add missing dependencies to package json 2026-08-26 03:55:07 +02:00
Aaron Kelbsch 34fbfaba50 docs: add contribution info to readme 2026-08-26 03:53:57 +02:00
Aaron Kelbsch f8bde94864 chore: update package.json 2026-08-26 03:53:56 +02:00
Haydon Ryan 858dc40f52 Update to use Node 24 (#48) 2026-03-20 10:35:40 -06:00
Daniel Szoke 3ae01282e2 docs: Fix README typo ("crate" → "crate") (#42) 2025-10-30 11:31:47 -06:00
11 changed files with 105 additions and 52 deletions
+2 -5
View File
@@ -6,17 +6,14 @@
"parserOptions": { "parserOptions": {
"project": "./tsconfig.json" "project": "./tsconfig.json"
}, },
"plugins": [ "plugins": ["@typescript-eslint"],
"@typescript-eslint"
],
"extends": [ "extends": [
"eslint:recommended", "eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking", "plugin:@typescript-eslint/recommended-requiring-type-checking",
"plugin:@typescript-eslint/recommended", "plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended", "plugin:prettier/recommended",
"prettier", "prettier"
"prettier/@typescript-eslint"
], ],
"rules": { "rules": {
"@typescript-eslint/explicit-function-return-type": 0 "@typescript-eslint/explicit-function-return-type": 0
+1 -1
View File
@@ -9,7 +9,7 @@ jobs:
- name: Create npm configuration - name: Create npm configuration
run: echo "//npm.pkg.github.com/:_authToken=${token}" >> ~/.npmrc run: echo "//npm.pkg.github.com/:_authToken=${token}" >> ~/.npmrc
env: env:
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GH_TOKEN }}
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
+6
View File
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Changed
- Update the GitHub Action runtime and local Node tooling target to Node 24.
## [1.4.1] - 2023-04-04 ## [1.4.1] - 2023-04-04
### Fixed ### Fixed
+2 -1
View File
@@ -61,7 +61,7 @@ github-token:
This action only raises issues when it's triggered from a `cron` scheduled workflow or on manual `workflow_dispatch` This action only raises issues when it's triggered from a `cron` scheduled workflow or on manual `workflow_dispatch`
When running the action as scheduled it will crate issues but e.g. in PR / push fails the action. When running the action as scheduled it will create issues but e.g. in PR / push fails the action.
#### Limitations #### Limitations
@@ -104,6 +104,7 @@ For each new advisory (including informal) an issue will be created:
| `token` | ✓ | [GitHub token], usually a `${{ secrets.GITHUB_TOKEN }}` | string | | | `token` | ✓ | [GitHub token], usually a `${{ secrets.GITHUB_TOKEN }}` | string | |
| `ignore` | | Comma-separated list of advisory ids to ignore | string | | | `ignore` | | Comma-separated list of advisory ids to ignore | string | |
| `working-directory`| | The directory of the Cargo.toml / Cargo.lock files to scan. | string | `.` | | `working-directory`| | The directory of the Cargo.toml / Cargo.lock files to scan. | string | `.` |
| `new-issue-labels` | | Comma-separated list of Labes to be added to new issues | string | `.` |
[GitHub token]: https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token [GitHub token]: https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token
+1 -1
View File
@@ -17,5 +17,5 @@ inputs:
default: . default: .
runs: runs:
using: 'node20' using: 'node24'
main: 'dist/index.js' main: 'dist/index.js'
+11 -3
View File
File diff suppressed because one or more lines are too long
+23 -8
View File
@@ -12,11 +12,13 @@
"@actions/core": "^1.11.1", "@actions/core": "^1.11.1",
"@actions/github": "^6.0.1", "@actions/github": "^6.0.1",
"@clechasseur/rs-actions-core": "^3.0.5", "@clechasseur/rs-actions-core": "^3.0.5",
"gitea-js": "^1.23.0",
"nunjucks": "^3.2.4" "nunjucks": "^3.2.4"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^29.5.12", "@types/jest": "^29.5.12",
"@types/node": "^20.11.17", "@types/node": "^24.0.0",
"@types/nunjucks": "^3.2.4",
"@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0", "@typescript-eslint/parser": "^6.21.0",
"@vercel/ncc": "0.38.1", "@vercel/ncc": "0.38.1",
@@ -2039,15 +2041,22 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "20.14.10", "version": "24.12.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.0.tgz",
"integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", "integrity": "sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"undici-types": "~5.26.4" "undici-types": "~7.16.0"
} }
}, },
"node_modules/@types/nunjucks": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/@types/nunjucks/-/nunjucks-3.2.6.tgz",
"integrity": "sha512-pHiGtf83na1nCzliuAdq8GowYiXvH5l931xZ0YEHaLMNFgynpEqx+IPStlu7UaDkehfvl01e4x/9Tpwhy7Ue3w==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/semver": { "node_modules/@types/semver": {
"version": "7.5.8", "version": "7.5.8",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
@@ -3716,6 +3725,12 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/gitea-js": {
"version": "1.23.0",
"resolved": "https://registry.npmjs.org/gitea-js/-/gitea-js-1.23.0.tgz",
"integrity": "sha512-f4+UPoWgDetZeZ+Awo5iI1nVdO5bjxA8+2QCeLo3oYWUYxKyzLfXgbW1EPD635wb8hLgS0DRBu5XhtiuYKEeUA==",
"license": "MIT"
},
"node_modules/glob": { "node_modules/glob": {
"version": "7.2.3", "version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@@ -6093,9 +6108,9 @@
} }
}, },
"node_modules/undici-types": { "node_modules/undici-types": {
"version": "5.26.5", "version": "7.16.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
+3 -1
View File
@@ -37,11 +37,13 @@
"@actions/core": "^1.11.1", "@actions/core": "^1.11.1",
"@actions/github": "^6.0.1", "@actions/github": "^6.0.1",
"@clechasseur/rs-actions-core": "^3.0.5", "@clechasseur/rs-actions-core": "^3.0.5",
"gitea-js": "^1.23.0",
"nunjucks": "^3.2.4" "nunjucks": "^3.2.4"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^29.5.12", "@types/jest": "^29.5.12",
"@types/node": "^20.11.17", "@types/node": "^24.0.0",
"@types/nunjucks": "^3.2.4",
"@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0", "@typescript-eslint/parser": "^6.21.0",
"@vercel/ncc": "0.38.1", "@vercel/ncc": "0.38.1",
+6 -1
View File
@@ -8,6 +8,7 @@ import { input } from '@clechasseur/rs-actions-core';
export interface Input { export interface Input {
token: string; token: string;
ignore: string[]; ignore: string[];
new_issue_labels: string[];
workingDirectory: string; workingDirectory: string;
} }
@@ -15,6 +16,10 @@ export function get(): Input {
return { return {
token: input.getInput('token', { required: true }), token: input.getInput('token', { required: true }),
ignore: input.getInputList('ignore', { required: false }), ignore: input.getInputList('ignore', { required: false }),
workingDirectory: input.getInput('working-directory', { required: false }) ?? '.', new_issue_labels: input.getInputList('new-issue-labels', {
required: false,
}),
workingDirectory:
input.getInput('working-directory', { required: false }) ?? '.',
}; };
} }
+7 -1
View File
@@ -54,6 +54,7 @@ function removeTrailingSlash(str) {
} }
export async function run(actionInput: input.Input): Promise<void> { export async function run(actionInput: input.Input): Promise<void> {
const labels = actionInput.new_issue_labels;
const ignore = actionInput.ignore; const ignore = actionInput.ignore;
const workingDirectory = removeTrailingSlash(actionInput.workingDirectory); const workingDirectory = removeTrailingSlash(actionInput.workingDirectory);
const report = await getData(ignore, workingDirectory); const report = await getData(ignore, workingDirectory);
@@ -97,7 +98,12 @@ export async function run(actionInput: input.Input): Promise<void> {
core.debug( core.debug(
'Action was triggered on a schedule event, creating an Issues report', 'Action was triggered on a schedule event, creating an Issues report',
); );
await reporter.reportIssues(actionInput.token, advisories, warnings); await reporter.reportIssues(
actionInput.token,
advisories,
warnings,
labels,
);
} else { } else {
core.debug( core.debug(
`Action was triggered on a ${github.context.eventName} event, creating a Check report`, `Action was triggered on a ${github.context.eventName} event, creating a Check report`,
+43 -30
View File
@@ -4,12 +4,9 @@ import * as core from '@actions/core';
import * as github from '@actions/github'; import * as github from '@actions/github';
import * as nunjucks from 'nunjucks'; import * as nunjucks from 'nunjucks';
import { checks } from '@clechasseur/rs-actions-core';
import * as interfaces from './interfaces'; import * as interfaces from './interfaces';
import * as templates from './templates'; import * as templates from './templates';
import { giteaApi } from 'gitea-js';
const pkg = require('../package.json'); // eslint-disable-line @typescript-eslint/no-var-requires
const USER_AGENT = `${pkg.name}/${pkg.version} (${pkg.bugs.url})`;
interface Stats { interface Stats {
critical: number; critical: number;
@@ -166,15 +163,22 @@ export async function reportCheck(
vulnerabilities: Array<interfaces.Vulnerability>, vulnerabilities: Array<interfaces.Vulnerability>,
warnings: Array<interfaces.Warning>, warnings: Array<interfaces.Warning>,
): Promise<void> { ): Promise<void> {
const client = github.getOctokit(token, {userAgent: USER_AGENT}); const { owner, repo } = github.context.repo;
const reporter = new checks.CheckReporter(client.rest, 'Security audit'); const api = giteaApi(process.env.GITHUB_SERVER_URL!, { token });
const stats = getStats(vulnerabilities, warnings); const stats = getStats(vulnerabilities, warnings);
const summary = getSummary(stats); const summary = getSummary(stats);
const body = {
description: 'Security Audit',
context: 'security-audit',
};
core.info(`Found ${summary}`); core.info(`Found ${summary}`);
try { try {
await reporter.startCheck('queued'); await api.repos.repoCreateStatus(owner, repo, github.context.sha, {
...body,
state: 'pending',
});
} catch (error) { } catch (error) {
// `GITHUB_HEAD_REF` is set only for forked repos, // `GITHUB_HEAD_REF` is set only for forked repos,
// so we can check if it is a fork and not a base repo. // so we can check if it is a fork and not a base repo.
@@ -205,16 +209,22 @@ See https://github.com/actions-rs/clippy-check/issues/2 for details.`);
} }
try { try {
const body = makeReport(vulnerabilities, warnings); // const body = makeReport(vulnerabilities, warnings);
const output = { // const output = {
title: 'Security advisories found', // title: 'Security advisories found',
summary: summary, // summary: summary,
text: body, // text: body,
}; // };
const status = stats.critical > 0 ? 'failure' : 'success'; const state = stats.critical > 0 ? 'failure' : 'success';
await reporter.finishCheck(status, output); await api.repos.repoCreateStatus(owner, repo, github.context.sha, {
...body,
state,
});
} catch (error) { } catch (error) {
await reporter.cancelCheck(); await api.repos.repoCreateStatus(owner, repo, github.context.sha, {
...body,
state: 'error',
});
throw error; throw error;
} }
@@ -235,13 +245,13 @@ async function alreadyReported(
advisoryId: string, advisoryId: string,
): Promise<boolean> { ): Promise<boolean> {
const { owner, repo } = github.context.repo; const { owner, repo } = github.context.repo;
const client = github.getOctokit(token, {userAgent: USER_AGENT}); const api = giteaApi(process.env.GITHUB_SERVER_URL!, { token });
const results = await client.rest.search.issuesAndPullRequests({ const results = await api.repos.issueListIssues(owner, repo, {
q: `${advisoryId} in:title repo:${owner}/${repo}`, q: advisoryId,
per_page: 1, // eslint-disable-line @typescript-eslint/camelcase limit: 1,
}); });
if (results.data.total_count > 0) { if (results.data.length > 0) {
core.info( core.info(
`Seems like ${advisoryId} is mentioned already in the issues/PRs, \ `Seems like ${advisoryId} is mentioned already in the issues/PRs, \
will not report an issue against it`, will not report an issue against it`,
@@ -256,10 +266,11 @@ export async function reportIssues(
token: string, token: string,
vulnerabilities: Array<interfaces.Vulnerability>, vulnerabilities: Array<interfaces.Vulnerability>,
warnings: Array<interfaces.Warning>, warnings: Array<interfaces.Warning>,
labels: string[],
): Promise<void> { ): Promise<void> {
const { owner, repo } = github.context.repo; const { owner, repo } = github.context.repo;
const client = github.getOctokit(token, {userAgent: USER_AGENT}); const api = giteaApi(process.env.GITHUB_SERVER_URL!, { token });
for (const vulnerability of vulnerabilities) { for (const vulnerability of vulnerabilities) {
const reported = await alreadyReported( const reported = await alreadyReported(
@@ -273,12 +284,13 @@ export async function reportIssues(
const body = nunjucks.renderString(templates.VULNERABILITY_ISSUE, { const body = nunjucks.renderString(templates.VULNERABILITY_ISSUE, {
vulnerability: vulnerability, vulnerability: vulnerability,
}); });
const issue = await client.rest.issues.create({ const issue = await api.repos.issueCreateIssue(owner, repo, {
owner: owner,
repo: repo,
title: `${vulnerability.advisory.id}: ${vulnerability.advisory.title}`, title: `${vulnerability.advisory.id}: ${vulnerability.advisory.title}`,
body: body, body,
}); });
for (const label of labels) {
core.warning(`Unable to add label ${label}`);
}
core.info( core.info(
`Created an issue for ${vulnerability.advisory.id}: ${issue.data.html_url}`, `Created an issue for ${vulnerability.advisory.id}: ${issue.data.html_url}`,
); );
@@ -314,12 +326,13 @@ export async function reportIssues(
warning: warning, warning: warning,
advisory: advisory, advisory: advisory,
}); });
const issue = await client.rest.issues.create({ const issue = await api.repos.issueCreateIssue(owner, repo, {
owner: owner,
repo: repo,
title: `${advisory.id}: ${advisory.title}`, title: `${advisory.id}: ${advisory.title}`,
body: body, body,
}); });
for (const label of labels) {
core.warning(`Unable to add label ${label}`);
}
core.info( core.info(
`Created an issue for ${advisory.id}: ${issue.data.html_url}`, `Created an issue for ${advisory.id}: ${issue.data.html_url}`,
); );