Skip to content

Commit

Permalink
Merge pull request #13 from British-Oceanographic-Data-Centre/feature…
Browse files Browse the repository at this point in the history
…/shared-ci

Shared CI configurations
leobr29 authored Nov 29, 2024
2 parents b9cf444 + 19c9da1 commit 21b1184
Showing 20 changed files with 384 additions and 293 deletions.
64 changes: 64 additions & 0 deletions .github/workflows/component-container-image-security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Generic security scan

on:
workflow_call:
inputs:
context:
description: "Path to the Dockerfile directory to analyse"
required: true
default: "."
type: string
image-path:
description: "Path of the docker image to analyse"
default: "ghcr.io/${{ github.repository }}/app"
type: string

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

jobs:
security-dependency-trivy:
name: Trivy dependency scan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
# need to format as github.repository contains uppercase
# and pull request workflow contains slashes
- id: format
name: Format proper image path and tag
env:
IMAGE_PATH: ${{ inputs.image-path }}
run: |
echo "image-tag=${GITHUB_REF_NAME/\//-}" >> $GITHUB_OUTPUT
echo "image-path=${IMAGE_PATH@L}" >> $GITHUB_OUTPUT
- name: Build Docker image
uses: docker/build-push-action@v6
if: ${{ github.event_name != 'release' }}
with:
context: "{{defaultContext}}:${{ inputs.context }}"
tags: "${{ steps.format.outputs.image-path }}:${{ steps.format.outputs.image-tag }}"
push: false
- name: Run Trivy vulnerability scanner
uses: aquasecurity/[email protected]
env:
TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db,aquasec/trivy-db,ghcr.io/aquasecurity/trivy-db
TRIVY_JAVA_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-java-db,aquasec/trivy-java-db,ghcr.io/aquasecurity/trivy-java-db
with:
image-ref: "${{ steps.format.outputs.image-path }}:${{ steps.format.outputs.image-tag }}"
format: 'sarif'
output: 'trivy-results.sarif'
vuln-type: "os,library"
severity: "CRITICAL,HIGH"
exit-code: "1"
ignore-unfixed: true
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: 'trivy-results.sarif'
- name: Inspect bandit SARIF report
if: always()
run: cat trivy-results.sarif
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
name: Java Docker
name: Build and push Docker image

on:
push:
branches:
- main
paths:
- "java-demo/**"
pull_request:
paths:
- "java-demo/**"
release:
types: [created]
workflow_call:
inputs:
context:
description: "Path to the Dockerfile directory to build"
default: "."
type: string
image-path:
description: "Path of the docker image Tag"
default: "ghcr.io/${{ github.repository }}/app"
type: string

jobs:
container-image-build:
name: Docker
runs-on: ubuntu-latest
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- id: format
name: Lowercase repository path
uses: ASzc/change-string-case-action@v1
with:
string: ${{ inputs.image-path }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
if: ${{ github.event_name == 'release' }}
@@ -31,12 +37,13 @@ jobs:
uses: docker/build-push-action@v6
if: ${{ github.event_name != 'release' }}
with:
context: "{{defaultContext}}:java-demo"
context: "{{defaultContext}}:${{ inputs.context }}"
tags: "${{ steps.format.outputs.lowercase }}:develop"
push: false
- name: Build and push
uses: docker/build-push-action@v6
if: ${{ github.event_name == 'release' }}
with:
context: "{{defaultContext}}:java-demo"
context: "{{defaultContext}}:${{ inputs.context }}"
tags: "${{ steps.format.outputs.lowercase }}:${{ github.ref_name }}"
push: true
tags: "ghcr.io/british-oceanographic-data-centre/amrit-repos/java/app:${{ github.ref_name }}"
27 changes: 27 additions & 0 deletions .github/workflows/component-java-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Java Lint

on:
workflow_call:
inputs:
context:
description: "Path to the module to lint"
default: ""
type: string
java-version:
description: "Java version"
default: "21"
type: string

jobs:
java-linter-spotless:
name: Lint with spotless
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: ${{ inputs.java-version }}
- name: Run Spotless lint
working-directory: ./${{ inputs.context }}
run: ./mvnw spotless:check
32 changes: 32 additions & 0 deletions .github/workflows/component-java-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Java Tests

on:
workflow_call:
inputs:
context:
description: "Path to the module to lint"
default: ""
type: string
java-version:
description: "Java version"
default: "21"
type: string

jobs:
java-test-maven:
name: Test with Maven
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: ${{ inputs.java-version }}
- name: Run Maven run tests
working-directory: ./${{ inputs.context }}
run: ./mvnw clean test
- name: Publish Test Report
uses: mikepenz/action-junit-report@v5
if: always()
with:
report_paths: '**/target/**/TEST-*.xml'
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
name: Python Tox
name: Python Linting

on:
push:
branches:
# Run on our main branch
- main
paths:
- example-python/**
pull_request:
# Run for any pull requests
paths:
- example-python/**
workflow_call:
inputs:
context:
description: "Path to the module to lint"
default: ""
type: string

jobs:
tox:
runs-on: ubuntu-latest
@@ -20,21 +17,21 @@ jobs:
python-version: ["3.10", "3.11", "3.12", "3.13"]
tox-job: ["test", "build", "lint", "type"]
steps:
- uses: actions/checkout@v4 # Checkout the current branch/merge state
- name: Set up Python ${{ matrix.python-version }} # Get Python ready to use
- uses: actions/checkout@v4 # Checkout the current branch/merge state
- name: Set up Python ${{ matrix.python-version }} # Get Python ready to use
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies # Get Tox and Poetry ready
working-directory: ./example-python
- name: Install dependencies # Get Tox and Poetry ready
working-directory: ./${{ inputs.context }}
run: |
python -m pip install --upgrade pip
python -m pip install tox tox-gh-actions
curl -sSL https://install.python-poetry.org | python -
tox depends --recreate
# Run Tox jobs
- name: Tox (${{ matrix.tox-job }})
working-directory: ./example-python
working-directory: ./${{ inputs.context }}
run: |
poetry config virtualenvs.create false
poetry install --no-root --with ${{ matrix.tox-job }}
Original file line number Diff line number Diff line change
@@ -2,30 +2,30 @@
name: Python Security

on:
push:
branches:
# Run on our main branch
- main
paths:
- example-python/**
pull_request:
# Run for any pull requests
paths:
- example-python/**
workflow_call:
inputs:
context:
description: "Path to the module to lint"
default: ""
type: string

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

jobs:
# https://github.com/marketplace/actions/anchore-container-scan
dependency-check:
name: Grype & Pip Audit dependency scan
runs-on: ubuntu-latest
permissions:
# Required for uploading sarif file
security-events: write
steps:
- uses: actions/checkout@v4 # Checkout the current branch/merge state
- name: Grype Scan
uses: anchore/scan-action@v3
id: grype-scan
with:
path: example-python
path: ${{ inputs.context }}
- name: Upload grype sarif file
if: always()
uses: github/codeql-action/upload-sarif@v3
@@ -38,8 +38,9 @@ jobs:
- name: Pip Audit
uses: pypa/[email protected]
with:
inputs: example-python
inputs: ${{ inputs.context }}
code-check:
name: Bandit scan
runs-on: ubuntu-latest
strategy:
matrix:
@@ -54,21 +55,21 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies # Install bandit
working-directory: ./example-python
working-directory: ./${{ inputs.context }}
run: |
python -m pip install --upgrade pip
python -m pip install bandit[toml,sarif]
- name: Run Bandit
working-directory: ./example-python
working-directory: ./${{ inputs.context }}
# Run bandit and output to sarif file
run: |
bandit -r . -c pyproject.toml -f sarif -o bandit.sarif
- name: Upload bandit sarif file
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: example-python/bandit.sarif
sarif_file: ${{ inputs.context }}/bandit.sarif
category: bandit-python-analysis
- name: Inspect bandit SARIF report
if: always()
run: cat example-python/bandit.sarif
run: cat ${{ inputs.context }}/bandit.sarif
21 changes: 21 additions & 0 deletions .github/workflows/component-ts-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Typescript Lint

on:
workflow_call:
inputs:
context:
description: "Path to the module to lint"
default: ""
type: string

jobs:
eslint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install modules
working-directory: ./${{ inputs.context }}
run: npm install
- name: Run ESLint
working-directory: ./${{ inputs.context }}
run: npm run lint
Original file line number Diff line number Diff line change
@@ -5,13 +5,15 @@
#
# This workflow file requires a free account on Bearer.com to manage findings, notifications and more.
# See https://docs.bearer.com/guides/bearer-cloud/
name: Bearer
name: Typescript security

on:
pull_request:

schedule:
- cron: '*/15 * * * *'
workflow_call:
inputs:
context:
description: "Path to the module to lint"
default: ""
type: string

permissions:
contents: read # for actions/checkout to fetch code
@@ -20,6 +22,7 @@ permissions:

jobs:
bearer:
name: Bearer scan
runs-on: ubuntu-latest
steps:
# Checkout project source
@@ -29,4 +32,4 @@ jobs:
id: report
uses: bearer/bearer-action@828eeb928ce2f4a7ca5ed57fb8b59508cb8c79bc
with:
path: typescript-demo
path: ${{ inputs.context }}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
name: Typescript Test

on:
push:
paths:
- typescript-demo/**
pull_request:
paths:
- 'typescript-demo/**'
workflow_call:
inputs:
context:
description: "Path to the module to lint"
default: ""
type: string

jobs:
test:
@@ -16,57 +16,40 @@ jobs:
# Checkout the repository
- name: Checkout code
uses: actions/checkout@v4

# Set up Node.js environment
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: "22"

# Install dependencies in the `typescript-demo` folder
# Install dependencies in the context folder
- name: Install dependencies
run: npm install
working-directory: ./typescript-demo

working-directory: ./${{ inputs.context }}
# Build the application
- name: Build the application
run: npm run build
working-directory: ./typescript-demo

working-directory: ./${{ inputs.context }}
# Start the application
- name: Start the application
run: npm start &
working-directory: ./typescript-demo
working-directory: ./${{ inputs.context }}
env:
NODE_ENV: test

- name: Run Jest tests
run: npx jest --ci
working-directory: ./typescript-demo
working-directory: ./${{ inputs.context }}
env:
JEST_JUNIT_OUTPUT_DIR: test-results
JEST_JUNIT_OUTPUT_NAME: junit.xml

- name: Upload test results
uses: actions/upload-artifact@v4
with:
name: jest-test-results
path: ./typescript-demo/test-results/junit.xml

- name: Display test results in summary
uses: dorny/test-reporter@v1
- name: Publish Test Report
uses: mikepenz/action-junit-report@v5
if: always()
with:
name: Jest Tests
path: ./typescript-demo/test-results/junit.xml
reporter: jest-junit
fail-on-error: 'true'
use-actions-summary: 'true'

report_paths: '**/junit.xml'
# Run Cypress tests
- name: Run Cypress tests
uses: cypress-io/github-action@v4
with:
working-directory: ./typescript-demo
working-directory: ./${{ inputs.context }}
wait-on: http://localhost:3000
wait-on-timeout: 60
spec: cypress/e2e/**/*.cy.js
23 changes: 0 additions & 23 deletions .github/workflows/java-lint.yml

This file was deleted.

37 changes: 0 additions & 37 deletions .github/workflows/java-security.yml

This file was deleted.

23 changes: 0 additions & 23 deletions .github/workflows/java-test.yml

This file was deleted.

44 changes: 0 additions & 44 deletions .github/workflows/python-docker.yaml

This file was deleted.

42 changes: 0 additions & 42 deletions .github/workflows/ts-build.yml

This file was deleted.

25 changes: 0 additions & 25 deletions .github/workflows/ts-lint.yml

This file was deleted.

37 changes: 37 additions & 0 deletions .github/workflows/workflow-java.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Java Workflow

on:
push:
branches:
# Run on our main branch
- main
paths:
- java-demo/**
pull_request:
# Run for any pull requests
paths:
- java-demo/**
release:
types: [created]

jobs:
java-linting:
uses: ./.github/workflows/component-java-lint.yml
with:
context: java-demo
java-testing:
uses: ./.github/workflows/component-java-test.yml
with:
context: java-demo
container-image-build:
needs: [java-linting, java-testing]
uses: ./.github/workflows/component-container-image.yml
with:
context: java-demo
image-path: ghcr.io/british-oceanographic-data-centre/amrit-repos/java/app
container-image-security:
needs: [container-image-build]
uses: ./.github/workflows/component-container-image-security.yml
with:
context: java-demo
image-path: ghcr.io/british-oceanographic-data-centre/amrit-repos/java/app
37 changes: 37 additions & 0 deletions .github/workflows/workflow-python.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Python Workflow

on:
push:
branches:
# Run on our main branch
- main
paths:
- example-python/**
pull_request:
# Run for any pull requests
paths:
- example-python/**
release:
types: [created]

jobs:
python-linting:
uses: ./.github/workflows/component-python-lint.yml
with:
context: example-python
python-security:
uses: ./.github/workflows/component-python-security.yml
with:
context: example-python
container-image-build:
needs: [python-linting, python-security]
uses: ./.github/workflows/component-container-image.yml
with:
context: example-python
image-path: ghcr.io/british-oceanographic-data-centre/amrit-repos/python/app
container-image-security:
needs: [container-image-build]
uses: ./.github/workflows/component-container-image-security.yml
with:
context: example-python
image-path: ghcr.io/british-oceanographic-data-centre/amrit-repos/python/app
41 changes: 41 additions & 0 deletions .github/workflows/workflow-ts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: TypeScript Workflow

on:
push:
branches:
# Run on our main branch
- main
paths:
- typescript-demo/**
pull_request:
# Run for any pull requests
paths:
- typescript-demo/**
release:
types: [created]

jobs:
ts-linting:
uses: ./.github/workflows/component-ts-lint.yml
with:
context: typescript-demo
ts-test:
uses: ./.github/workflows/component-ts-test.yml
with:
context: typescript-demo
ts-security:
uses: ./.github/workflows/component-ts-security.yml
with:
context: typescript-demo
container-image-build:
needs: [ts-linting, ts-test, ts-security]
uses: ./.github/workflows/component-container-image.yml
with:
context: typescript-demo
image-path: ghcr.io/british-oceanographic-data-centre/amrit-repos/typescript/app
container-image-security:
needs: [container-image-build]
uses: ./.github/workflows/component-container-image-security.yml
with:
context: typescript-demo
image-path: ghcr.io/british-oceanographic-data-centre/amrit-repos/typescript/app
46 changes: 38 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -3,69 +3,93 @@
A series of "best practice" examples for code quality, testing, and style for open source code written under the AMRIT banner, leveraging CI/CD pipelines for package publication and automatic enforcement of these requirements.

## Languages

- Java
- Python
- TypeScript

## Requirements

- Code linting
- Code testing
- Code type-checking (Python-only)
- Containerised development environments and application images

## Implementation and Frameworks

| Language | Linting | Testing | Typing | Security Scanning | Containerisation | Images | CI/CD |
| :------: | :-----: | :-----: | :----: | :---------------: | :--------------: | :----: | :---: |
| Java | [Spotless](https://github.com/search?q=repo%3ABritish-Oceanographic-Data-Centre%2Famrit-repos%20%3CgroupId%3Ecom.diffplug.spotless%3C%2FgroupId%3E&type=code) | [JUnit](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/tree/main/java-demo/src/test) | [N/A](## "Java is a statically typed language.") | N/A | [Docker](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/blob/main/java-demo/Dockerfile) + [Compose](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/blob/main/java-demo/compose.yaml) | [GitHub Packages](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/pkgs/container/amrit-repos%2Fjava%2Fapp) | [GitHub Actions](https://github.com/search?q=repo%3ABritish-Oceanographic-Data-Centre%2Famrit-repos+path%3A.github%2Fworkflows%2Fjava-*.yml+&type=code) |
| Python | [Ruff](https://github.com/search?q=repo%3ABritish-Oceanographic-Data-Centre%2Famrit-repos%20%5Btool.ruff%5D&type=code) + [Bandit](https://github.com/PyCQA/bandit) | [PyTest](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/blob/main/example-python/tests/test_main.py) | [MyPy](https://github.com/search?q=repo%3ABritish-Oceanographic-Data-Centre%2Famrit-repos%20%5Btestenv%3Atype%5D&type=code) | [Grype](https://github.com/anchore/grype) + [pip-audit](https://pypi.org/project/pip-audit/) | [Docker](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/blob/main/example-python/Dockerfile) | [GitHub Packages](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/pkgs/container/amrit-repos%2Fpython%2Fapp) | [GitHub Actions](https://github.com/search?q=repo%3ABritish-Oceanographic-Data-Centre%2Famrit-repos+path%3A.github%2Fworkflows%2Fpython-*.yaml+&type=code) |
| TypeScript | [ESLint](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/blob/main/typescript-demo/.eslintrc.json) | [N/A](## "In future, we expect to use front-end testing frameworks such as Cypress.") | [Strict](https://github.com/search?q=repo%3ABritish-Oceanographic-Data-Centre%2Famrit-repos+path%3Atypescript-demo%2Ftsconfig.json+%22strict%22%3A+&type=code) | [Bearer](https://docs.bearer.com/) | [Docker](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/blob/main/typescript-demo/Dockerfile) | [GitHub Packages](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/pkgs/container/amrit-repos%2Ftypescript%2Fapp) | [GitHub Actions](https://github.com/search?q=repo%3ABritish-Oceanographic-Data-Centre%2Famrit-repos+path%3A.github%2Fworkflows%2Fts-*.yml&type=code) |
| Java | [Spotless](https://github.com/search?q=repo%3ABritish-Oceanographic-Data-Centre%2Famrit-repos%20%3CgroupId%3Ecom.diffplug.spotless%3C%2FgroupId%3E&type=code) | [JUnit](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/tree/main/java-demo/src/test) | [N/A](## "Java is a statically typed language.") | [Trivy](https://trivy.dev/v0.57/) | [Docker](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/blob/main/java-demo/Dockerfile) + [Compose](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/blob/main/java-demo/compose.yaml) | [GitHub Packages](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/pkgs/container/amrit-repos%2Fjava%2Fapp) | [GitHub Actions](https://github.com/search?q=repo%3ABritish-Oceanographic-Data-Centre%2Famrit-repos+path%3A.github%2Fworkflows%2Fjava-*.yml+&type=code) |
| Python | [Ruff](https://github.com/search?q=repo%3ABritish-Oceanographic-Data-Centre%2Famrit-repos%20%5Btool.ruff%5D&type=code) + [Bandit](https://github.com/PyCQA/bandit) | [PyTest](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/blob/main/example-python/tests/test_main.py) | [MyPy](https://github.com/search?q=repo%3ABritish-Oceanographic-Data-Centre%2Famrit-repos%20%5Btestenv%3Atype%5D&type=code) | [Grype](https://github.com/anchore/grype) + [pip-audit](https://pypi.org/project/pip-audit/) + [Trivy](https://trivy.dev/v0.57/) | [Docker](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/blob/main/example-python/Dockerfile) | [GitHub Packages](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/pkgs/container/amrit-repos%2Fpython%2Fapp) | [GitHub Actions](https://github.com/search?q=repo%3ABritish-Oceanographic-Data-Centre%2Famrit-repos+path%3A.github%2Fworkflows%2Fpython-*.yaml+&type=code) |
| TypeScript | [ESLint](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/blob/main/typescript-demo/.eslintrc.json) | [N/A](## "In future, we expect to use front-end testing frameworks such as Cypress.") | [Strict](https://github.com/search?q=repo%3ABritish-Oceanographic-Data-Centre%2Famrit-repos+path%3Atypescript-demo%2Ftsconfig.json+%22strict%22%3A+&type=code) | [Bearer](https://docs.bearer.com/) + [Trivy](https://trivy.dev/v0.57/) | [Docker](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/blob/main/typescript-demo/Dockerfile) | [GitHub Packages](https://github.com/British-Oceanographic-Data-Centre/amrit-repos/pkgs/container/amrit-repos%2Ftypescript%2Fapp) | [GitHub Actions](https://github.com/search?q=repo%3ABritish-Oceanographic-Data-Centre%2Famrit-repos+path%3A.github%2Fworkflows%2Fts-*.yml&type=code) |

All of our chosen linting rules, tests, as well as package builds can be executed both locally on developer machines and in the cloud via GitHub Actions. Security checks can be executed via GitHub Actions.

### Java

See [detailled documentation](./java-demo/README.md).

#### Spotless

[Spotless](https://github.com/diffplug/spotless) is a static analysis and formatting tool for multiple languages, including Java. Our Java example runs spotless via Maven.

#### JUnit
[JUnit](https://junit.org/) is a testing framework for Java. The unit tests we have written for this example run automatically at build time.

[JUnit](https://junit.org/) is a testing framework for Java. The unit tests we have written for this example run automatically at build time.

#### Maven

Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project's build, reporting and documentation from a central piece of information.

### Python

#### Ruff

[Ruff](https://github.com/astral-sh/ruff) is a static analysis and formatting tool for Python, serving as an aggregator of rules multiple analysis and formatting tools. Our Python example is subject to a customised collection of Ruff rules including (but not limited to) those from [Black](https://black.readthedocs.io/en/stable/), [PyLint](https://pylint.readthedocs.io/en/latest/), and [Flake8](https://github.com/pycqa/flake8). Our Ruff rules are evaluated via Tox.

#### Bandit

[Bandit](https://github.com/PyCQA/bandit) is a tool designed to find common security issues in Python code. It is worth noting that Ruff implements a subset of Bandit checks, however we have disabled these in preference of explicitly using Bandit itself to perform these.

#### PyTest

[PyTest](https://docs.pytest.org/en/stable/) is a testing framework for Python. The unit tests we have written for this example are run via Tox.

#### MyPy

[MyPy](https://github.com/python/mypy) is a static type checker for Python. It is run against our example code via Tox.

#### Tox

[Tox](https://tox.wiki/en/4.23.2/) is a tool for automating the application of tests and other jobs against Python code.

#### Grype

[Grype](https://github.com/anchore/grype) is a vulnerability scanner for container images and filesystems.

#### Pip Audit

[pip-audit](https://pypi.org/project/pip-audit/) is a tool for scanning Python environments for packages with known vulnerabilities.

### TypeScript

See [detailled documentation](./typescript-demo/README.md).

#### ESLint

[ESLint](https://eslint.org/) is a static analysis and formatting tool for JavaScript with official plugins supporting NextJS and TypeScript.

#### Strict mode

TypeScript features optional static typing via [strict mode](https://www.typescriptlang.org/tsconfig/#strict), which has been enabled for our example code.

### Security scans
A tool called Bearer is performing these; there is a GitHub action which, on a pull request, will scan all the files within the typescript-demo folder.

A developer can find the latest instructions on installing and running Bearer locally [here](https://docs.bearer.com/reference/installation/).
A tool called Bearer is performing these; there is a GitHub action which, on a pull request, will scan all the files within the typescript-demo folder.

A developer can find the latest instructions on installing and running Bearer locally [here](https://docs.bearer.com/reference/installation/).
For quick reference, see the steps below.

```shell
$ curl -sfL https://raw.githubusercontent.com/Bearer/bearer/main/contrib/install.sh | sh
# that will install locally into a ./bin/ folder - either keep it here or more it into a $path location
@@ -75,13 +99,17 @@ $ curl -sfL https://raw.githubusercontent.com/Bearer/bearer/main/contrib/install
# making sure your are in the root of the AMRIT project
$ bearer scan typescript-demo
```

### Docker and Docker Compose

[Docker](https://www.docker.com/) is a tool for the development and execution of OCI-standard container images. It is used to build and run images for our Java, Python, and TypeScript example applications.

[Docker Compose](https://docs.docker.com/compose/) is a tool for the orchestration of simple container-based applications, using declarative configuration files to manage single or multi-image applications that may be made up of multiple discrete services or single, self-sufficient images. It is used to run our Java example application.

### GitHub Packages

[GitHub Packages](https://docs.github.com/en/packages/learn-github-packages/introduction-to-github-packages) is a software package hosting service that is tightly integrated with GitHub's ecosystem. By hosting our container images here, we make the process of downloading and running these example applications trivial:

```console
$ docker run -it -p 3000:3000 ghcr.io/british-oceanographic-data-centre/amrit-repos/typescript/app:v0.0.1
Unable to find image 'ghcr.io/british-oceanographic-data-centre/amrit-repos/typescript/app:v0.0.1' locally
@@ -104,11 +132,13 @@ Status: Downloaded newer image for ghcr.io/british-oceanographic-data-centre/amr
✓ Starting...
✓ Ready in 58ms
```

```console
$ firefox http://localhost:3000
firefox http://localhost:3000
```
![image](https://github.com/user-attachments/assets/87cdc725-f981-400b-ad86-e8351fb2af2d)

![image](https://github.com/user-attachments/assets/87cdc725-f981-400b-ad86-e8351fb2af2d)

### GitHub Actions

[GitHub Actions](https://github.com/features/actions) is a CI/CD service that allows developers to run customised jobs for building, testing, and deploying code in a variety of different ways. Our example code is tested and built in the cloud via GitHub actions, then automatically included in container image builds that are published to the GitHub Packages namespace associated with this repository whenever a new release is created.
11 changes: 8 additions & 3 deletions example-python/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.12 AS base
FROM python:3.12-slim AS base
# Common base image.
LABEL org.opencontainers.image.authors="matcaz@noc.ac.uk"
LABEL org.opencontainers.image.description="Example OCI image for a Python application."
@@ -11,8 +11,13 @@ LABEL org.opencontainers.image.vendor="Advance Marine Research Infrastructures T
# Install Poetry for dependency management.
ENV POETRY_HOME=/opt/poetry
ENV PATH="${POETRY_HOME}/bin:${PATH}"
RUN mkdir -p /opt/poetry/project /opt/poetry/bin
RUN curl -sSL https://install.python-poetry.org | python -

RUN \
apt -y update && \
apt -y install curl && \
apt clean && \
mkdir -p /opt/poetry/project /opt/poetry/bin && \
curl -sSL https://install.python-poetry.org | python -

# Install dependencies.
COPY pyproject.toml poetry*.lock README.md /opt/poetry/project/

0 comments on commit 21b1184

Please sign in to comment.