diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 0000000..d3c5679 --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,29 @@ +# Dependency Review Action +# +# This Action scans dependency manifest files changed in pull requests +# and surfaces vulnerable or policy-violating dependencies. +name: 'Dependency review' + +on: + pull_request: + branches: ["main"] + +permissions: + contents: read + +jobs: + dependency-review: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + steps: + - name: 'Checkout repository' + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + with: + persist-credentials: false + + - name: 'Dependency Review' + uses: actions/dependency-review-action@56339e523c0409420f6c2c9a2f4292bbb3c07dd3 + with: + comment-summary-in-pr: always diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 16455ce..61b8bf9 100755 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,30 +6,29 @@ on: - 'v*' permissions: - contents: write - packages: read + contents: read jobs: build-windows: runs-on: windows-latest steps: - name: Check out Git repository - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + with: + persist-credentials: false - name: Install Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 with: - node-version: 18 + node-version: 20 + package-manager-cache: false - name: Install dependencies - run: npm install + run: npm ci - name: Prepare build run: node scripts/prepare-build.js windows - - name: Build CSS - run: npm run build:css - - name: Build Webpack run: npm run build:webpack @@ -39,25 +38,32 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload Windows Artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f with: name: windows-artifacts - path: dist/*.exe + path: | + dist/*.exe + dist/*.msi + dist/latest*.yml + dist/*.blockmap retention-days: 5 build-linux: runs-on: ubuntu-latest steps: - name: Check out Git repository - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + with: + persist-credentials: false - name: Install Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 with: - node-version: 18 + node-version: 20 + package-manager-cache: false - name: Install dependencies - run: npm install + run: npm ci - name: Install required system packages run: | @@ -91,9 +97,6 @@ jobs: fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n'); " - - name: Build CSS - run: npm run build:css - - name: Build Webpack run: npm run build:webpack @@ -103,32 +106,36 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload Linux Artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f with: name: linux-artifacts - path: dist/*.AppImage + path: | + dist/*.AppImage + dist/*.AppImage.zsync + dist/latest*.yml + dist/*.blockmap retention-days: 5 build-macos: runs-on: macos-latest steps: - name: Check out Git repository - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + with: + persist-credentials: false - name: Install Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 with: - node-version: 18 + node-version: 20 + package-manager-cache: false - name: Install dependencies - run: npm install + run: npm ci - name: Prepare build run: node scripts/prepare-build.js mac - - name: Build CSS - run: npm run build:css - - name: Build Webpack run: npm run build:webpack @@ -138,22 +145,27 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload macOS Artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f with: name: macos-artifacts path: | dist/*.dmg dist/*.zip + dist/latest*.yml + dist/*.blockmap retention-days: 5 create-release: needs: [build-windows, build-linux, build-macos] runs-on: ubuntu-latest + permissions: + contents: write steps: - name: Check out Git repository - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: fetch-depth: 0 + persist-credentials: false - name: Get version from tag id: get_version @@ -161,7 +173,7 @@ jobs: - name: Get Changelog Entry id: changelog_reader - uses: mindsers/changelog-reader-action@v2 + uses: mindsers/changelog-reader-action@32aa5b4c155d76c94e4ec883a223c947b2f02656 with: validation_level: warn path: ./CHANGELOG.md @@ -169,30 +181,30 @@ jobs: continue-on-error: true - name: Download Windows artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 with: name: windows-artifacts path: artifacts - name: Download Linux artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 with: name: linux-artifacts path: artifacts - name: Download macOS artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 with: name: macos-artifacts path: artifacts - name: Create Release - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 with: name: Release ${{ steps.get_version.outputs.VERSION }} body: ${{ steps.changelog_reader.outputs.changes || 'No changelog provided' }} draft: true files: | - artifacts/* + artifacts/** env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/sbom.yml b/.github/workflows/sbom.yml new file mode 100644 index 0000000..c6b6b10 --- /dev/null +++ b/.github/workflows/sbom.yml @@ -0,0 +1,47 @@ +name: SBOM Generation + +on: + push: + branches: ['main'] + pull_request: + branches: ['main'] + workflow_dispatch: + +permissions: + contents: read + +jobs: + sbom: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + with: + persist-credentials: false + + - name: Setup Node.js + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 + with: + node-version: 20 + package-manager-cache: false + + - name: Install dependencies + run: | + if [ -f package-lock.json ]; then + npm ci --ignore-scripts + else + npm install --ignore-scripts --no-audit --no-fund + fi + + - name: Generate CycloneDX SBOM + run: | + mkdir -p dist/security/sbom + npx --yes @cyclonedx/cyclonedx-npm --output-format json --output-file dist/security/sbom/sbom.cyclonedx.json + + - name: Upload SBOM artifact + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f + with: + name: sbom-cyclonedx + path: dist/security/sbom/sbom.cyclonedx.json + retention-days: 30 diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml new file mode 100644 index 0000000..e3d5b24 --- /dev/null +++ b/.github/workflows/sonarcloud.yml @@ -0,0 +1,65 @@ +name: SonarCloud QA Gate + +on: + workflow_dispatch: + pull_request: + push: + branches: + - main + +permissions: + contents: read + +jobs: + sonarcloud: + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + with: + fetch-depth: 0 + persist-credentials: false + + - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 + with: + node-version: 20 + package-manager-cache: false + + - name: Install dependencies + run: npm install + + - name: Run tests with coverage + continue-on-error: true + run: npm test -- --coverage --runInBand + + - name: Ensure coverage report exists + run: | + if [ ! -f coverage/lcov.info ]; then + mkdir -p coverage + touch coverage/lcov.info + fi + + - name: SonarCloud scan + continue-on-error: true + uses: SonarSource/sonarqube-scan-action@a31c9398be7ace6bbfaf30c0bd5d415f843d45e9 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + with: + args: > + -Dsonar.host.url=https://sonarcloud.io + -Dsonar.organization=${{ vars.SONAR_ORGANIZATION || 'codingworkflow' }} + -Dsonar.projectKey=${{ vars.SONAR_PROJECT_KEY || 'codingworkflow_ai-code-fusion' }} + -Dsonar.javascript.lcov.reportPaths=coverage/lcov.info + + - name: SonarCloud quality gate + continue-on-error: true + uses: SonarSource/sonarqube-quality-gate-action@cf038b0e0cdecfa9e56c198bbb7d21d751d62c3b + with: + scanMetadataReportFile: .scannerwork/report-task.txt + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: https://sonarcloud.io + timeout-minutes: 5 diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..7190a60 --- /dev/null +++ b/renovate.json @@ -0,0 +1,3 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json" +}