@@ -12,3 +12,10 @@ Dockerfile
Dockerfile.web
docker-compose.yml
dockersetup.py
+*.pem
+*.log
+*.patch
+*.zst
+.venv
+.idea
+.DS_Store
new file mode 100644
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: MIT
+
+name: CI
+
+on:
+ push:
+ branches: [master,master-next]
+ pull_request:
+ branches: [master]
+
+permissions:
+ contents: read
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ timeout-minutes: 30
+ steps:
+ - uses: actions/checkout@v5
+
+ - name: Build image and run tests
+ run: docker/run-tests.sh
new file mode 100644
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: MIT
+
+name: Safety
+
+on:
+ push:
+ branches: [master,master-next]
+ schedule:
+ - cron: '0 6 * * 1'
+ workflow_dispatch:
+
+permissions:
+ contents: read
+
+jobs:
+ scan:
+ runs-on: ubuntu-latest
+ timeout-minutes: 15
+ env:
+ SAFETY_API_KEY: ${{ secrets.SAFETY_API_KEY }}
+ # Steps are skipped where the secret isn't set, e.g. other forks.
+ steps:
+ - uses: actions/checkout@v5
+
+ - name: Build image
+ if: env.SAFETY_API_KEY != ''
+ run: docker build -t layerindex-test .
+
+ # Scans the versions actually installed in the image, so ranges in
+ # requirements.txt (e.g. Django) can't hide vulnerable releases.
+ - name: Safety scan
+ if: env.SAFETY_API_KEY != ''
+ run: |
+ mkdir safety-scan
+ cp .safety-project.ini safety-scan/
+ docker run --rm layerindex-test pip3 freeze > safety-scan/requirements.txt
+ # typer pinned: newer releases break safety 3.7.0 ("no active click context")
+ python3 -m venv /tmp/safety
+ /tmp/safety/bin/pip install -q safety==3.7.0 typer==0.23.0
+ /tmp/safety/bin/safety scan --target safety-scan --detailed-output
new file mode 100644
@@ -0,0 +1,5 @@
+[project]
+id = layerindex-web
+url = /codebases/layerindex-web/findings
+name = layerindex-web
+
new file mode 100755
@@ -0,0 +1,41 @@
+#!/bin/sh
+# layerindex-web - run the test suite in the production image against a
+# throwaway MariaDB. Used by CI; can also be run locally from the repo root.
+#
+# SPDX-License-Identifier: MIT
+
+set -e
+
+IMAGE=${IMAGE:-layerindex-test}
+NET=layerindex-test
+DB=layerindex-test-db
+
+docker build -t "$IMAGE" .
+
+docker network create $NET >/dev/null
+trap 'docker rm -f $DB >/dev/null; docker network rm $NET >/dev/null' EXIT
+
+# Alias "layersdb" matches the default DATABASE_HOST in docker/settings.py;
+# testingpw is that file's default password, not a real secret.
+docker run -d --name $DB --network $NET --network-alias layersdb \
+ -e MARIADB_ROOT_PASSWORD=testingpw mariadb:10.11 \
+ --character-set-server=utf8mb4 >/dev/null
+until docker exec $DB healthcheck.sh --connect --innodb_initialized >/dev/null 2>&1; do
+ sleep 1
+done
+
+# Runs as root only to prepare the container: tests/test_update.py rewrites
+# settings.py and bitbake writes its lock file next to it, the update scripts
+# expect bitbake already fetched, and the tests commit to git and call tree.
+docker run --rm --network $NET -u root \
+ -e SECRET_KEY=ci-only \
+ -e GIT_AUTHOR_NAME=ci -e GIT_AUTHOR_EMAIL=ci@example.com \
+ -e GIT_COMMITTER_NAME=ci -e GIT_COMMITTER_EMAIL=ci@example.com \
+ -v "$PWD/tests:/src/tests:ro" -w /opt/layerindex "$IMAGE" sh -ec '
+ apt-get update -qq && apt-get install -y -qq tree >/dev/null
+ cp -r /src/tests /opt/layerindex/
+ chown -R layers /opt/layerindex
+ su layers -s /bin/sh -c "set -e
+ git clone -q https://git.openembedded.org/bitbake /opt/workdir/https___git_openembedded_org_bitbake
+ pip3 install -q --user --no-warn-script-location pytest==9.0.3 pytest-django==4.12.0
+ python3 -m pytest -rfE -p no:cacheprovider tests/"'
docker/run-tests.sh builds the production image, starts a throwaway MariaDB 10.11 on a private network and runs the full test suite inside the image, so tests/test_update.py can run bitbake on Linux. Test data comes only from migrations and public git repositories; the database password is the public default from docker/settings.py. The script can also be run locally from the repository root. A separate Safety workflow runs 'safety scan' on 'pip freeze' output from the image, so version ranges in requirements.txt (e.g. Django) cannot hide vulnerable releases. It runs on push, weekly and on demand, so newly published vulnerabilities are reported without a code change, and is skipped when SAFETY_API_KEY is not available. Also keep local keys, logs, patches and virtualenvs out of the Docker build context. AI-Generated: Claude Opus 5.5 Signed-off-by: Tim Orling <tim.orling@konsulko.com> --- .dockerignore | 7 ++++++ .github/workflows/ci.yml | 22 +++++++++++++++++++ .github/workflows/safety.yml | 40 +++++++++++++++++++++++++++++++++++ .safety-project.ini | 5 +++++ docker/run-tests.sh | 41 ++++++++++++++++++++++++++++++++++++ 5 files changed, 115 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/safety.yml create mode 100644 .safety-project.ini create mode 100755 docker/run-tests.sh