From 8414f628e57747f93627fbed0bf298c75772cab4 Mon Sep 17 00:00:00 2001 From: Ministry of Justice Analytical Platform Robot <125977389+moj-data-platform-robot@users.noreply.github.com> Date: Tue, 16 Apr 2024 12:04:17 +0100 Subject: [PATCH] Initial commit --- .devcontainer/devcontainer-lock.json | 22 ++++++ .devcontainer/devcontainer.json | 18 +++++ .editorconfig | 23 ++++++ .github/CODEOWNERS | 1 + .github/dependabot.yml | 16 +++++ .github/workflows/build-and-test.yml | 30 ++++++++ .github/workflows/dependency-review.yml | 28 ++++++++ .github/workflows/release.yml | 55 ++++++++++++++ .github/workflows/scan-image.yml | 57 +++++++++++++++ .github/workflows/super-linter.yml | 35 +++++++++ .gitignore | 10 +++ Dockerfile | 49 +++++++++++++ LICENSE | 21 ++++++ Makefile | 18 +++++ README.md | 96 +++++++++++++++++++++++++ test/container-structure-test.yml | 25 +++++++ 16 files changed, 504 insertions(+) create mode 100644 .devcontainer/devcontainer-lock.json create mode 100644 .devcontainer/devcontainer.json create mode 100644 .editorconfig create mode 100644 .github/CODEOWNERS create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/build-and-test.yml create mode 100644 .github/workflows/dependency-review.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/scan-image.yml create mode 100644 .github/workflows/super-linter.yml create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 test/container-structure-test.yml diff --git a/.devcontainer/devcontainer-lock.json b/.devcontainer/devcontainer-lock.json new file mode 100644 index 0000000..45d524e --- /dev/null +++ b/.devcontainer/devcontainer-lock.json @@ -0,0 +1,22 @@ +{ + "features": { + "ghcr.io/devcontainers/features/docker-in-docker:2": { + "version": "2.10.2", + "resolved": "ghcr.io/devcontainers/features/docker-in-docker@sha256:23ae11a86089da5f0b98a6edd603f91831802b7f2d5ef1e104e1b94a3beb546c", + "integrity": "sha256:23ae11a86089da5f0b98a6edd603f91831802b7f2d5ef1e104e1b94a3beb546c" + }, + "ghcr.io/ministryofjustice/devcontainer-feature/container-structure-test:0": { + "version": "0.0.2", + "resolved": "ghcr.io/ministryofjustice/devcontainer-feature/container-structure-test@sha256:a0d81a6b8be5deae2fc41edf007a8f0efe794b4ebf0880265643b4a06edf16c6", + "integrity": "sha256:a0d81a6b8be5deae2fc41edf007a8f0efe794b4ebf0880265643b4a06edf16c6", + "dependsOn": [ + "ghcr.io/devcontainers/features/docker-in-docker:2" + ] + }, + "ghcr.io/ministryofjustice/devcontainer-feature/static-analysis:0": { + "version": "0.0.3", + "resolved": "ghcr.io/ministryofjustice/devcontainer-feature/static-analysis@sha256:81efa45affc66c168d273817f6f86a64f90715e9482eb7f6e3b33af006a2236c", + "integrity": "sha256:81efa45affc66c168d273817f6f86a64f90715e9482eb7f6e3b33af006a2236c" + } + } +} \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..175f026 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,18 @@ +{ + "name": "analytical-platform-image-build-template", + "image": "ghcr.io/ministryofjustice/devcontainer-base:latest", + "features": { + "ghcr.io/devcontainers/features/docker-in-docker:2": {}, + "ghcr.io/ministryofjustice/devcontainer-feature/container-structure-test:0": {}, + "ghcr.io/ministryofjustice/devcontainer-feature/static-analysis:0": {} + }, + "customizations": { + "vscode": { + "extensions": [ + "EditorConfig.EditorConfig", + "GitHub.vscode-github-actions", + "GitHub.vscode-pull-request-github" + ] + } + } +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..3ba6594 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,23 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +# This file is autogenerated +[.devcontainer/devcontainer-lock.json] +end_of_line = unset +insert_final_newline = unset + +[*.json] +indent_style = space +indent_size = 2 + +[*.sh] +indent_style = space +indent_size = 2 + +[*.yml] +indent_style = space +indent_size = 2 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..1138e83 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @ministryofjustice/analytical-platform diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..37b6438 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,16 @@ +--- +version: 2 + +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + - package-ecosystem: "devcontainers" + directory: "/" + schedule: + interval: "daily" + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml new file mode 100644 index 0000000..97162cf --- /dev/null +++ b/.github/workflows/build-and-test.yml @@ -0,0 +1,30 @@ +--- +name: Build and Test + +on: + pull_request: + branches: + - main + +permissions: {} + +jobs: + build-and-test: + name: Build and Test + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout + id: checkout + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + + - name: Set Up Container Structure Test + id: setup_container_structure_test + uses: ministryofjustice/github-actions/setup-container-structure-test@bdab1cff6d23336b6d5adc662fb57af72f0ae160 # v17.1.0 + + - name: Build and Test + id: build_and_test + shell: bash + run: | + make test diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 0000000..49f374e --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,28 @@ +--- +name: Dependency Review + +on: + pull_request: + types: + - edited + - opened + - reopened + - synchronize + +permissions: {} + +jobs: + dependency-review: + name: Dependency Review + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout + id: checkout + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + + - name: Dependency Review + uses: actions/dependency-review-action@5bbc3ba658137598168acb2ab73b21c432dd411b # v4.2.5 + with: + fail-on-severity: critical diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..90f86bb --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,55 @@ +--- +name: Release + +on: + push: + tags: + - "*" + +permissions: {} + +jobs: + release: + name: Release + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + packages: write + steps: + - name: Checkout + id: checkout + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + + - name: Install cosign + id: install_cosign + uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 # v3.5.0 + + - name: Log in to GitHub Container Registry + id: login_ghcr + uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and Push + id: build_and_push + uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0 + with: + push: true + tags: ghcr.io/${{ github.repository }}:${{ github.ref_name }} + + - name: Sign + id: sign + shell: bash + run: | + cosign sign --yes ghcr.io/${{ github.repository }}@${{ steps.build_and_push.outputs.digest }} + + - name: Verify + id: verify + run: | + cosign verify \ + --certificate-oidc-issuer=https://token.actions.githubusercontent.com \ + --certificate-identity=https://github.com/${{ github.repository }}/.github/workflows/release.yml@refs/tags/${{ github.ref_name }} \ + ghcr.io/${{ github.repository }}@${{ steps.build_and_push.outputs.digest }} diff --git a/.github/workflows/scan-image.yml b/.github/workflows/scan-image.yml new file mode 100644 index 0000000..697bc55 --- /dev/null +++ b/.github/workflows/scan-image.yml @@ -0,0 +1,57 @@ +--- +name: Scan Image + +on: + pull_request: + branches: + - main + +permissions: {} + +jobs: + scan-image: + name: Scan Image + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write + steps: + - name: Checkout + id: checkout + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + + - name: Build Image + id: build_image + uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0 + with: + push: false + load: true + tags: analytical-platform-image-build-template + + - name: Scan Image + id: scan_image + uses: aquasecurity/trivy-action@d710430a6722f083d3b36b8339ff66b32f22ee55 # v0.19.0 + with: + image-ref: analytical-platform-image-build-template + exit-code: 1 + format: sarif + output: trivy-results.sarif + severity: CRITICAL + limit-severities-for-sarif: true + + - name: Upload SARIF + if: always() + id: upload_sarif + uses: github/codeql-action/upload-sarif@df5a14dc28094dc936e103b37d749c6628682b60 # v3.25.0 + with: + sarif_file: trivy-results.sarif + + - name: Scan Image (On SARIF Scan Failure) + if: failure() && steps.scan_image.outcome == 'failure' + id: scan_image_on_failure + uses: aquasecurity/trivy-action@d710430a6722f083d3b36b8339ff66b32f22ee55 # v0.19.0 + with: + image-ref: analytical-platform-image-build-template + exit-code: 1 + format: table + severity: CRITICAL diff --git a/.github/workflows/super-linter.yml b/.github/workflows/super-linter.yml new file mode 100644 index 0000000..cb153e7 --- /dev/null +++ b/.github/workflows/super-linter.yml @@ -0,0 +1,35 @@ +--- +name: Super-Linter + +on: + pull_request: + branches: + - main + types: + - edited + - opened + - reopened + - synchronize + +permissions: {} + +jobs: + super-linter: + name: Super-Linter + runs-on: ubuntu-latest + permissions: + contents: read + statuses: write + steps: + - name: Checkout + id: checkout + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + fetch-depth: 0 + + - name: Run Super-Linter + id: super_linter + uses: super-linter/super-linter/slim@92e2606383320f72e6129f8a50d8537cf9c84ed6 # v6.3.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa69ef3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +.env +.terraform/ +coverage/ +venv/ +env/ +.DS_STORE +.vscode +*.code-workspace +*.sha256 +terraform.tfstate diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4063e61 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,49 @@ +# checkov:skip=CKV_DOCKER_2:Healthcheck instructions have not been added to container images +# This image is an example base image for this template and can be replaced to fit user needs +FROM public.ecr.aws/ubuntu/ubuntu@sha256:12fb86d81bc4504d8261a91c83c54b9e5dcdf1d833ba0fe42ec9e0ee09a2b0ba + +LABEL org.opencontainers.image.vendor="Ministry of Justice" \ + org.opencontainers.image.authors="Analytical Platform (analytical-platform@digital.justice.gov.uk)"\ + org.opencontainers.image.title="{image title}" \ + org.opencontainers.image.description="{decription}" \ + org.opencontainers.image.url="{your repo url}" + +ENV CONTAINER_USER="analyticalplatform" \ + CONTAINER_UID="1000" \ + CONTAINER_GROUP="analyticalplatform" \ + CONTAINER_GID="1000" \ + DEBIAN_FRONTEND="noninteractive" + +SHELL ["/bin/bash", "-e", "-u", "-o", "pipefail", "-c"] + +# User +RUN < +```text +├── .devcontainer +│ ├── devcontainer.json +│ └── devcontainer-lock.json +├── Dockerfile +├── .editorconfig +├── .github +│ ├── CODEOWNERS +│ ├── dependabot.yml +│ └── workflows +│ ├── build-and-test.yml +│ ├── dependency-review.yml +│ ├── release.yml +│ ├── scan-image.yml +│ └── super-linter.yml +├── .gitignore +├── LICENSE +├── Makefile +├── README.md +└── test + └── container-structure-test.yml +``` + +## Setup Instructions + +Once you've created your repository using this template, perform the following steps: + +### Update README + +Edit this README.md file to document your project accurately. Take the time to create a clear, engaging, and informative README.md file. Include information like what your project does, how to install and run it, how to contribute, and any other pertinent details. + +### Update repository description + +After you've created your repository, GitHub provides a brief description field that appears on the top of your repository's main page. This is a summary that gives visitors quick insight into the project. Using this field to provide a succinct overview of your repository is highly recommended. + +This description and your README.md will be one of the first things people see when they visit your repository. It's a good place to make a strong, concise first impression. Remember, this is often visible in search results on GitHub and search engines, so it's also an opportunity to help people discover your project. + +### Grant Team Permissions + +Assign permissions to the appropriate Ministry of Justice teams. Ensure at least one team is granted Admin permissions. Whenever possible, assign permissions to teams rather than individual users. + +### Read about the GitHub Repository Standards + +Familiarise yourself with the Ministry of Justice GitHub Repository Standards. These standards ensure consistency, maintainability, and best practices across all our repositories. + +You can find the standards [here](https://operations-engineering.service.justice.gov.uk/documentation/services/repository-standards.html). + +Please read and understand these standards thoroughly and enable them when you feel comfortable. + +### Modify the GitHub Repository Standards Badge + +Once you've ensured that all the [GitHub Repository Standards](https://operations-engineering.service.justice.gov.uk/documentation/services/repository-standards.html) have been applied to your repository, it's time to update the Ministry of Justice (MoJ) Compliance Badge located in the README file. + +The badge demonstrates that your repository is compliant with MoJ's standards. Please follow these [instructions](https://operations-engineering.service.justice.gov.uk/documentation/runbooks/services/add-repo-badge.html) to modify the badge URL to reflect the status of your repository correctly. + +**Please note** the badge will not function correctly if your repository is internal or private. In this case, you may remove the badge from your README. + +### Manage Outside Collaborators + +To add an Outside Collaborator to the repository, follow the guidelines detailed [here](https://github.com/ministryofjustice/github-collaborators). + +### Update CODEOWNERS + +(Optional) Modify the CODEOWNERS file to specify the teams or users authorized to approve pull requests. + +### Configure Dependabot + +Adapt the dependabot.yml file to match your project's [dependency manager](https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem) and to enable [automated pull requests for package updates](https://docs.github.com/en/code-security/supply-chain-security). + +### Dependency Review + +If your repository is private with no GitHub Advanced Security license, remove the `.github/workflows/dependency-review.yml` file. + +### Dockerfile + +Make sure to add your own build logic to the bottom of the `Dockerfile`. + +### Tests + +> [!NOTE] +> No application testing has been added to this template, this is to be implemented by the developer as required. + +Please make sure to add any additional container structure tests needed to the `container-structure-test.yml`. diff --git a/test/container-structure-test.yml b/test/container-structure-test.yml new file mode 100644 index 0000000..8948a04 --- /dev/null +++ b/test/container-structure-test.yml @@ -0,0 +1,25 @@ +--- +schemaVersion: 2.0.0 + +containerRunOptions: + user: "analyticalplatform" + +commandTests: + - name: "ubuntu" + command: "grep" + args: ["DISTRIB_RELEASE", "/etc/lsb-release"] + expectedOutput: ["DISTRIB_RELEASE=22.04"] + + - name: "whoami" + command: "whoami" + expectedOutput: ["analyticalplatform"] + + - name: "user" + command: "id" + args: ["--user", "analyticalplatform"] + expectedOutput: ["1000"] + + - name: "groups" + command: "id" + args: ["--groups", "analyticalplatform"] + expectedOutput: ["100"]