mirror of
https://github.com/ivuorinen/actions.git
synced 2026-02-12 06:46:45 +00:00
Feat/ci actions @coderabbitio (#61)
* feat(ci): create daily releases * feat(ci): better splitting of security-suite steps * fix(ci): update new-release workflow
This commit is contained in:
36
.github/tag-changelog-config.js
vendored
Normal file
36
.github/tag-changelog-config.js
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
module.exports = {
|
||||||
|
types: [
|
||||||
|
{ types: ['feat', 'feature', 'Feat'], label: '🎉 New Features' },
|
||||||
|
{ types: ['fix', 'bugfix', 'Fix'], label: '🐛 Bugfixes' },
|
||||||
|
{ types: ['improvements', 'enhancement'], label: '🔨 Improvements' },
|
||||||
|
{ types: ['perf'], label: '🏎️ Performance Improvements' },
|
||||||
|
{ types: ['build', 'ci'], label: '🏗️ Build System' },
|
||||||
|
{ types: ['refactor'], label: '🪚 Refactors' },
|
||||||
|
{ types: ['doc', 'docs'], label: '📚 Documentation Changes' },
|
||||||
|
{ types: ['config'], label: '🪛 Configuration Changes' },
|
||||||
|
{ types: ['test', 'tests'], label: '🔍 Tests' },
|
||||||
|
{ types: ['style', 'codestyle', 'lint'], label: '💅 Code Style Changes' },
|
||||||
|
{ types: ['chore', 'Chore', 'deps', 'Deps'], label: '🧹 Chores' },
|
||||||
|
{ types: ['other', 'Other'], label: 'Other Changes' },
|
||||||
|
],
|
||||||
|
|
||||||
|
excludeTypes: [],
|
||||||
|
|
||||||
|
renderTypeSection: function(label, commits) {
|
||||||
|
let text = `\n## ${label}\n\n`
|
||||||
|
|
||||||
|
commits.forEach(commit => {
|
||||||
|
const scope = commit.scope ? `**${commit.scope}:** ` : ''
|
||||||
|
text += `- ${scope}${commit.subject}\n`
|
||||||
|
})
|
||||||
|
|
||||||
|
return text
|
||||||
|
},
|
||||||
|
|
||||||
|
renderChangelog: function(release, changes) {
|
||||||
|
const now = new Date()
|
||||||
|
const d = now.toISOString().substring(0, 10)
|
||||||
|
const header = `# ${release} - ${d}\n`
|
||||||
|
return header + changes + '\n\n'
|
||||||
|
},
|
||||||
|
}
|
||||||
46
.github/workflows/new-release.yml
vendored
Normal file
46
.github/workflows/new-release.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
name: Release Daily State
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 21 * * *' # 00:00 at Europe/Helsinki
|
||||||
|
|
||||||
|
permissions: read-all
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
new-daily-release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
created: ${{ steps.daily-version.outputs.created }}
|
||||||
|
version: ${{ steps.daily-version.outputs.version }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
|
|
||||||
|
- name: Create tag if necessary
|
||||||
|
uses: fregante/daily-version-action@fb1a60b7c4daf1410cd755e360ebec3901e58588 # v2
|
||||||
|
id: daily-version
|
||||||
|
|
||||||
|
- name: Create changelog text
|
||||||
|
if: steps.daily-version.outputs.created
|
||||||
|
id: changelog
|
||||||
|
uses: loopwerk/tag-changelog@941366edb8920e2071eae0449031830984b9f26e # v1.3.0
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
config_file: .github/tag-changelog-config.js
|
||||||
|
|
||||||
|
- name: Create release
|
||||||
|
if: steps.daily-version.outputs.created
|
||||||
|
uses: ncipollo/release-action@440c8c1cb0ed28b9f43e4d1d670870f059653174 # v1.16.0
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
tag: ${{ steps.daily-version.outputs.version }}
|
||||||
|
name: Release ${{ steps.daily-version.outputs.version }}
|
||||||
|
body: ${{ steps.changelog.outputs.changes }}
|
||||||
|
allowUpdates: true
|
||||||
113
.github/workflows/security-suite.yml
vendored
113
.github/workflows/security-suite.yml
vendored
@@ -28,25 +28,18 @@ concurrency:
|
|||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
env:
|
|
||||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
security-checks:
|
check-secrets:
|
||||||
name: Security Checks
|
name: Check Required Secrets
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 30
|
outputs:
|
||||||
|
run_snyk: ${{ steps.check.outputs.run_snyk }}
|
||||||
permissions:
|
run_slack: ${{ steps.check.outputs.run_slack }}
|
||||||
security-events: write
|
run_sonarcloud: ${{ steps.check.outputs.run_sonarcloud }}
|
||||||
pull-requests: write
|
|
||||||
statuses: write
|
|
||||||
issues: write
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check Required Secrets
|
- name: Check Required Secrets
|
||||||
id: check-secrets
|
id: check
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
{
|
{
|
||||||
@@ -55,7 +48,6 @@ jobs:
|
|||||||
echo "run_sonarcloud=false"
|
echo "run_sonarcloud=false"
|
||||||
} >> "$GITHUB_OUTPUT"
|
} >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
# Check secrets
|
|
||||||
if [ -n "${{ secrets.SNYK_TOKEN }}" ]; then
|
if [ -n "${{ secrets.SNYK_TOKEN }}" ]; then
|
||||||
echo "run_snyk=true" >> "$GITHUB_OUTPUT"
|
echo "run_snyk=true" >> "$GITHUB_OUTPUT"
|
||||||
else
|
else
|
||||||
@@ -74,11 +66,15 @@ jobs:
|
|||||||
echo "::warning::SONAR_TOKEN not set - SonarCloud analysis will be skipped"
|
echo "::warning::SONAR_TOKEN not set - SonarCloud analysis will be skipped"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
owasp:
|
||||||
with:
|
name: OWASP Dependency Check
|
||||||
fetch-depth: 0
|
runs-on: ubuntu-latest
|
||||||
|
needs: check-secrets
|
||||||
|
permissions:
|
||||||
|
security-events: write
|
||||||
|
|
||||||
# OWASP Dependency Check
|
steps:
|
||||||
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
- name: Run OWASP Dependency Check
|
- name: Run OWASP Dependency Check
|
||||||
uses: dependency-check/Dependency-Check_Action@3102a65fd5f36d0000297576acc56a475b0de98d # main
|
uses: dependency-check/Dependency-Check_Action@3102a65fd5f36d0000297576acc56a475b0de98d # main
|
||||||
with:
|
with:
|
||||||
@@ -90,53 +86,92 @@ jobs:
|
|||||||
--enableRetired
|
--enableRetired
|
||||||
--enableExperimental
|
--enableExperimental
|
||||||
--failOnCVSS 7
|
--failOnCVSS 7
|
||||||
|
|
||||||
- name: Upload OWASP Results
|
- name: Upload OWASP Results
|
||||||
uses: github/codeql-action/upload-sarif@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
|
uses: github/codeql-action/upload-sarif@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
|
||||||
with:
|
with:
|
||||||
sarif_file: reports/dependency-check-report.sarif
|
sarif_file: reports/dependency-check-report.sarif
|
||||||
category: owasp-dependency-check
|
category: owasp-dependency-check
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||||
|
with:
|
||||||
|
name: owasp-results
|
||||||
|
path: reports/dependency-check-report.sarif
|
||||||
|
|
||||||
# Snyk Analysis
|
snyk:
|
||||||
- name: Setup Node.js
|
name: Snyk Security Scan
|
||||||
if: steps.check-secrets.outputs.run_snyk == 'true'
|
runs-on: ubuntu-latest
|
||||||
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
needs: check-secrets
|
||||||
|
if: needs.check-secrets.outputs.run_snyk == 'true'
|
||||||
|
permissions:
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||||
with:
|
with:
|
||||||
node-version: 'lts/*'
|
node-version: 'lts/*'
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
|
|
||||||
- name: Run Snyk Scan
|
- name: Run Snyk Scan
|
||||||
id: snyk
|
|
||||||
if: steps.check-secrets.outputs.run_snyk == 'true'
|
|
||||||
uses: snyk/actions/node@cdb760004ba9ea4d525f2e043745dfe85bb9077e # master
|
uses: snyk/actions/node@cdb760004ba9ea4d525f2e043745dfe85bb9077e # master
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
env:
|
env:
|
||||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||||
with:
|
with:
|
||||||
args: --all-projects --sarif-file-output=snyk-results.sarif
|
args: --all-projects --sarif-file-output=snyk-results.sarif
|
||||||
|
|
||||||
- name: Upload Snyk Results
|
- name: Upload Snyk Results
|
||||||
if: steps.check-secrets.outputs.run_snyk == 'true'
|
|
||||||
uses: github/codeql-action/upload-sarif@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
|
uses: github/codeql-action/upload-sarif@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
|
||||||
with:
|
with:
|
||||||
sarif_file: snyk-results.sarif
|
sarif_file: snyk-results.sarif
|
||||||
category: snyk
|
category: snyk
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||||
|
with:
|
||||||
|
name: snyk-results
|
||||||
|
path: snyk-results.sarif
|
||||||
|
|
||||||
# OSSF Scorecard
|
scorecard:
|
||||||
|
name: OSSF Scorecard
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: check-secrets
|
||||||
|
permissions:
|
||||||
|
security-events: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
- name: Run Scorecard
|
- name: Run Scorecard
|
||||||
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
|
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
|
||||||
with:
|
with:
|
||||||
results_file: scorecard-results.sarif
|
results_file: scorecard-results.sarif
|
||||||
results_format: sarif
|
results_format: sarif
|
||||||
publish_results: true
|
publish_results: true
|
||||||
|
|
||||||
- name: Upload Scorecard Results
|
- name: Upload Scorecard Results
|
||||||
uses: github/codeql-action/upload-sarif@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
|
uses: github/codeql-action/upload-sarif@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
|
||||||
with:
|
with:
|
||||||
sarif_file: scorecard-results.sarif
|
sarif_file: scorecard-results.sarif
|
||||||
category: scorecard
|
category: scorecard
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||||
|
with:
|
||||||
|
name: scorecard-results
|
||||||
|
path: scorecard-results.sarif
|
||||||
|
|
||||||
|
analyze:
|
||||||
|
name: Analyze Results
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [check-secrets, owasp, scorecard, snyk]
|
||||||
|
if: always()
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
|
- name: Download scan results
|
||||||
|
uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.0
|
||||||
|
with:
|
||||||
|
path: ./results
|
||||||
|
|
||||||
# Analysis and Metrics
|
|
||||||
- name: Analyze Results
|
- name: Analyze Results
|
||||||
id: analysis
|
id: analysis
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||||
@@ -194,16 +229,16 @@ jobs:
|
|||||||
|
|
||||||
// Analyze all SARIF files
|
// Analyze all SARIF files
|
||||||
metrics.tools = {
|
metrics.tools = {
|
||||||
owasp: analyzeSarif('reports/dependency-check-report.sarif', 'OWASP'),
|
owasp: analyzeSarif('./results/owasp-results/dependency-check-report.sarif', 'OWASP'),
|
||||||
snyk: ${{ steps.check-secrets.outputs.run_snyk == 'true' }} ?
|
snyk: ${{ needs.check-secrets.outputs.run_snyk == 'true' }} ?
|
||||||
analyzeSarif('snyk-results.sarif', 'Snyk') : null,
|
analyzeSarif('./results/snyk-results/snyk-results.sarif', 'Snyk') : null,
|
||||||
scorecard: analyzeSarif('scorecard-results.sarif', 'Scorecard')
|
scorecard: analyzeSarif('./results/scorecard-results/scorecard-results.sarif', 'Scorecard')
|
||||||
};
|
};
|
||||||
|
|
||||||
// Save results for other steps
|
// Save results
|
||||||
fs.writeFileSync('security-results.json', JSON.stringify(metrics, null, 2));
|
fs.writeFileSync('security-results.json', JSON.stringify(metrics, null, 2));
|
||||||
|
|
||||||
// Set outputs for other steps
|
// Set outputs
|
||||||
core.setOutput('total_critical', metrics.vulnerabilities.critical);
|
core.setOutput('total_critical', metrics.vulnerabilities.critical);
|
||||||
core.setOutput('total_high', metrics.vulnerabilities.high);
|
core.setOutput('total_high', metrics.vulnerabilities.high);
|
||||||
|
|
||||||
@@ -313,7 +348,7 @@ jobs:
|
|||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
- name: Notify on Failure
|
- name: Notify on Failure
|
||||||
if: failure() && steps.check-secrets.outputs.run_slack == 'true'
|
if: failure() && needs.check-secrets.outputs.run_slack == 'true'
|
||||||
run: |
|
run: |
|
||||||
curl -X POST -H 'Content-type: application/json' \
|
curl -X POST -H 'Content-type: application/json' \
|
||||||
--data '{"text":"❌ Security checks failed! Check the logs for details."}' \
|
--data '{"text":"❌ Security checks failed! Check the logs for details."}' \
|
||||||
|
|||||||
Reference in New Issue
Block a user