diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..caec7b1 --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,23 @@ +name: Build and test against applicable Node versions + +on: + workflow_call: + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [18.x, 20.x] + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm run build --if-present + - run: npm run lint-test + - run: npm test \ No newline at end of file diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml new file mode 100644 index 0000000..de0c41b --- /dev/null +++ b/.github/workflows/codeql.yaml @@ -0,0 +1,40 @@ +name: "CodeQL Analysis" + +on: + workflow_dispatch: + push: + branches: [ master ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ master ] + types: [synchronize, opened, reopened] + schedule: + - cron: '22 17 * * 5' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'javascript' ] + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" \ No newline at end of file diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index e88b8ce..3913e1b 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -1,56 +1,82 @@ -name: Publish node.js package to npm whenever a tag is pushed to master +name: Create a release and publish image to ghcr whenever a version tag is pushed to master on: push: + branches: + - master tags: - 'v*' +env: + REGISTRY: ghcr.io + REGISTRY_USER: ${{ github.actor }} + REGISTRY_PASSWORD: ${{ github.token }} + IMAGE_NAME: ${{ github.repository }} + jobs: build: - - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [18.x, 20.x] - - steps: - - uses: actions/checkout@v2 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - run: npm install - - run: npm run build --if-present - - run: npm run lint-test - - run: npm test - + uses: ./.github/workflows/build.yaml + create-release: + name: Create release needs: build runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Create release - uses: actions/create-release@v1 + uses: comnoco/create-release@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions with: tag_name: ${{ github.ref }} release_name: ${{ github.ref }} + body: "See the [CHANGELOG](https://github.com/gchq/CyberChef-server/blob/master/CHANGELOG.md) and [commit messages](https://github.com/gchq/CyberChef-server/commits/master) for details." draft: false prerelease: false - publish-npm: + publish-ghcr: + name: Publish image to ghcr needs: build runs-on: ubuntu-latest + permissions: + packages: write + contents: read + attestations: write + id-token: write steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - name: Check out the repo + uses: actions/checkout@v4 + + - uses: docker/login-action@v3 with: - node-version: 18 - registry-url: https://registry.npmjs.org/ - - run: npm ci - - run: npm publish - env: - NODE_AUTH_TOKEN: ${{secrets.npm_token}} + registry: ${{ env.REGISTRY }} + username: ${{ env.REGISTRY_USER }} + password: ${{ env.REGISTRY_PASSWORD }} + + - name: Image Metadata + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=semver,pattern={{major}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{version}} + + - name: Build and push Docker image + id: push + uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 + with: + context: . + file: ./Dockerfile + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v2 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: true \ No newline at end of file diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index b555466..343dc21 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,4 +1,4 @@ -name: Run lint and tests +name: Test PRs to Master on: pull_request: @@ -7,20 +7,4 @@ on: jobs: build: - - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [18.x, 20.x] - - steps: - - uses: actions/checkout@v1 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - run: npm install - - run: npm run build --if-present - - run: npm run lint-test - - run: npm test \ No newline at end of file + uses: ./.github/workflows/build.yaml \ No newline at end of file diff --git a/.github/workflows/trivy.yaml b/.github/workflows/trivy.yaml new file mode 100644 index 0000000..393f5fc --- /dev/null +++ b/.github/workflows/trivy.yaml @@ -0,0 +1,53 @@ +name: Trivy scan + +on: + push: + branches: [ "master" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "master" ] + schedule: + - cron: '22 2 * * 5' + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +permissions: + contents: read + +jobs: + build: + permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results + actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status + name: Build + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + # docker image tags need to be lowercase so use this helper function to convert + - id: toLowerCase + uses: vishalmamidi/lowercase-action@v1 + with: + string: ${{ env.IMAGE_NAME }} + + - name: Build an image from Dockerfile + run: | + docker build -t ${{ env.REGISTRY }}/${{ steps.toLowerCase.outputs.lowercase }}:${{ github.sha }} . + + - name: Run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@7b7aa264d83dc58691451798b4d117d53d21edfe + with: + image-ref: '${{ env.REGISTRY }}/${{ steps.toLowerCase.outputs.lowercase }}:${{ github.sha }}' + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + severity: 'CRITICAL,HIGH' + + - name: Upload Trivy scan results to GitHub Security tab + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: 'trivy-results.sarif'