Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.git
.gitignore
__pycache__/
*.py[cod]
*.egg-info/
build/
dist/
.venv/
.pytest_cache/
.ruff_cache/
.mypy_cache/
.coverage
coverage.xml
test/
spike/
27 changes: 27 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
# Same grouping as ../FIA-API: one PR a week for Python, one a day for Actions.
#
# The base image is not Dependabot's to bump. `ARG RUNNER_TAG` in
# `container/mantid_python_script_lsp.D` decides which names a script may use, what warm-up costs and
# which algorithms exist, so moving it means the corpus check and a fresh set of measurements - see
# AGENTS.md, "Handling Dependabot PRs".

version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
groups:
python-packages:
patterns:
- "*"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
groups:
action-packages:
patterns:
- "*"
61 changes: 61 additions & 0 deletions .github/workflows/build-and-push.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
name: Build and Push Docker Images

# Only main publishes: the tag that gets promoted by GitOps is the digest of a commit on main, so a
# branch build has nowhere to go. This is the same shape as the other FIA services' publish workflows
# (build, push, then pin the new digest into the staging manifest in ../gitops).

on:
push:
branches:
- main

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository_owner }}

jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Check out code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Log in to the Container registry
uses: docker/login-action@8aa5831fb8d48d8f76594c7ddde61ae58019f550 # v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.WRITE_PACKAGE_TOKEN }}

- name: Build and push mantid-python-script-lsp Docker image
id: docker_build
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7
with:
file: ./container/mantid_python_script_lsp.D
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/mantid-python-script-lsp

- name: Checkout the Gitops repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: fiaisis/gitops
token: ${{ secrets.GITOPS_STAGING_EDIT_TOKEN }}

# The image is pinned by digest, not by tag, so a rebuild of the same content cannot silently move
# staging, and ArgoCD sees a real diff on every deploy.
- name: Edit the YAML mantid-python-script-lsp file for staging
uses: mikefarah/yq@59f7969b49b1d9608a37f7db006ce78f0610263e # v4.54.1
with:
cmd: yq e -i '.spec.template.spec.containers[] |= select(.name == "mantid-python-script-lsp").image = "ghcr.io/fiaisis/mantid-python-script-lsp@${{ steps.docker_build.outputs.digest }}"' './components/mantid-python-script-lsp/envs/staging/mantid-python-script-lsp.yml'

- name: Commit and push changes
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git commit -am "[CD] Update mantid-python-script-lsp with this commit ${{ github.event.head_commit.url}}"
git push
53 changes: 53 additions & 0 deletions .github/workflows/image-scan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
name: Image Scan

# Nightly rather than per-push: the base image is Mantid's, so the vulnerabilities found here are mostly
# whoever else's Debian packages are, on a schedule that catches them becoming public. A failing scan
# uploads SARIF to the Security tab instead of silently passing.

on:
schedule:
- cron: "49 8 * * *"
workflow_dispatch:

permissions:
contents: read
security-events: write

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository_owner }}

jobs:
trivy:
name: Trivy image scan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Build Docker image
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7
with:
file: ./container/mantid_python_script_lsp.D
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/mantid-python-script-lsp:${{ github.sha }}
push: false

- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@a9c7b0f06e461e9d4b4d1711f154ee024b8d7ab8 # v0.36.0
with:
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/mantid-python-script-lsp:${{ github.sha }}
format: sarif
output: trivy-results.sarif
ignore-unfixed: true
exit-code: 1

- name: Print results
run: cat trivy-results.sarif
if: failure()

- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@f3bbb05694c2f74569081c28664dec21 # v4.39.3
if: failure()
with:
sarif_file: trivy-results.sarif
78 changes: 78 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
# The unit suite and the static checks. Neither needs Mantid: the framework is stubbed in
# test/conftest.py, so CI runs on a plain Python - which is also the reason the suite must never import
# `mantid` at module scope. Building and pushing the image is deliberately not here: it belongs with the
# ghcr.io credentials and the image scanning, and a base image measured in gigabytes does not belong on
# every push to a feature branch.

on:
push:
pull_request:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
pytest:
runs-on: ubuntu-latest
steps:
- name: Checkout project
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Set up python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.13"

- name: Set up cache for Python dependencies
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }}
restore-keys: |
${{ runner.os }}-pip-

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install .[test]

- name: Run pytest
run: pytest test --random-order --random-order-bucket=global --cov=script_lsp --cov-branch --cov-report=term --cov-report=xml

static-analysis:
runs-on: ubuntu-latest
steps:
- name: Checkout project
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Set up python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.13"

- name: Set up cache for Python dependencies
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }}
restore-keys: |
${{ runner.os }}-pip-

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install .[formatting]

- name: Check formatting
run: ruff format --check .

- name: Lint
run: ruff check .

- name: Type check
run: mypy --strict script_lsp
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
__pycache__/
*.py[cod]
*.egg-info/
build/
dist/
.venv/
.pytest_cache/
.ruff_cache/
.mypy_cache/
.coverage
coverage.xml

# Built by spike/make_corpus.py from scripts pulled off a live FIA API. That is facility
# data-reduction code, so it stays out of the repository even though the generator is checked in.
spike/corpus/
Loading
Loading