150 lines
5.6 KiB
YAML
150 lines
5.6 KiB
YAML
name: ci
|
|
|
|
on:
|
|
push:
|
|
pull_request:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
quality:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
|
with:
|
|
persist-credentials: false
|
|
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
|
|
with:
|
|
python-version: "3.11"
|
|
- name: Install exact development dependencies
|
|
run: >-
|
|
python -m pip install --index-url https://pypi.org/simple/
|
|
--require-hashes -r requirements-dev.lock
|
|
- name: Validate workflows and shell
|
|
run: |
|
|
set -euo pipefail
|
|
archive=/tmp/actionlint.tar.gz
|
|
curl -fsSL --retry 3 --max-time 60 \
|
|
--proto '=https' --proto-redir '=https' --tlsv1.2 \
|
|
-A curl/8.4.0 \
|
|
https://github.com/rhysd/actionlint/releases/download/v1.7.12/actionlint_1.7.12_linux_amd64.tar.gz \
|
|
-o "$archive"
|
|
echo "8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8 $archive" \
|
|
| sha256sum -c -
|
|
tar -xzf "$archive" -C /tmp actionlint
|
|
/tmp/actionlint -no-color -pyflakes= -shellcheck= .gitea/workflows/*.yml
|
|
bash -n daemon-bootstrap.sh tools/release-tag.sh tools/resolve-release-identity.sh
|
|
- name: Lint and byte-compile
|
|
run: |
|
|
ruff check .
|
|
ruff format --check .
|
|
python -m py_compile ./*.py
|
|
- name: Build and inspect wheel and sdist
|
|
run: |
|
|
python -m build --no-isolation
|
|
python -m twine check dist/*
|
|
python tools/verify-wheel-contents.py dist/*.whl
|
|
|
|
unit-tests:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
python-version: ["3.11", "3.13"]
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
|
with:
|
|
persist-credentials: false
|
|
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
|
|
with:
|
|
python-version: ${{ matrix.python-version }}
|
|
- run: >-
|
|
python -m pip install --index-url https://pypi.org/simple/
|
|
--require-hashes -r requirements-dev.lock
|
|
- name: Run hermetic unit and integration tests
|
|
run: pytest -q -m "not e2e"
|
|
|
|
e2e:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
python-version: ["3.11", "3.13"]
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
|
with:
|
|
persist-credentials: false
|
|
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
|
|
with:
|
|
python-version: ${{ matrix.python-version }}
|
|
- run: >-
|
|
python -m pip install --index-url https://pypi.org/simple/
|
|
--require-hashes -r requirements-dev.lock
|
|
- name: Run fake Discord Gateway, REST, and Molecule UDS E2E
|
|
run: pytest -q -m e2e
|
|
|
|
sdk-contract:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
|
with:
|
|
persist-credentials: false
|
|
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
|
|
with:
|
|
python-version: "3.11"
|
|
- run: >-
|
|
python -m pip install --index-url https://pypi.org/simple/
|
|
--require-hashes -r requirements-dev.lock
|
|
- name: Install immutable public SDK 0.5.4
|
|
run: |
|
|
echo "molecule-ai-sdk==0.5.4 --hash=sha256:17898e0801c96c0eaf282750b03b348c0a82d6f7724ff4548e3d2633ce26802a" \
|
|
> /tmp/molecule-ai-sdk-requirements.txt
|
|
python -m pip install --no-deps --require-hashes \
|
|
--index-url https://git.moleculesai.app/api/packages/molecule-ai/pypi/simple/ \
|
|
-r /tmp/molecule-ai-sdk-requirements.txt
|
|
- name: Validate generated boundary and plugin bundle
|
|
run: |
|
|
SDK_CHANNEL="$(python -c 'import molecule_plugin.channel as c; print(c.__file__)')"
|
|
cmp "$SDK_CHANNEL" channel_sdk.py
|
|
python -m molecule_plugin channel-sdk check .
|
|
python -m molecule_plugin validate plugin .
|
|
|
|
security:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
|
with:
|
|
fetch-depth: 0
|
|
persist-credentials: false
|
|
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
|
|
with:
|
|
python-version: "3.11"
|
|
- run: >-
|
|
python -m pip install --index-url https://pypi.org/simple/
|
|
--require-hashes -r requirements-dev.lock
|
|
- name: Audit locked runtime dependencies
|
|
run: pip-audit --require-hashes --disable-pip -r requirements.lock
|
|
- name: Scan complete tracked history with verified gitleaks 8.30.1
|
|
run: |
|
|
set -euo pipefail
|
|
archive=/tmp/gitleaks.tar.gz
|
|
curl -fsSL --retry 3 --retry-all-errors --retry-max-time 60 \
|
|
--connect-timeout 10 --max-time 60 \
|
|
--proto '=https' --proto-redir '=https' --tlsv1.2 \
|
|
-A curl/8.4.0 \
|
|
https://github.com/gitleaks/gitleaks/releases/download/v8.30.1/gitleaks_8.30.1_linux_x64.tar.gz \
|
|
-o "$archive"
|
|
echo "551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb $archive" \
|
|
| sha256sum -c -
|
|
tar -xzf "$archive" -C /tmp gitleaks
|
|
/tmp/gitleaks git --no-banner --redact=100 --timeout 60 .
|
|
- name: Static security analysis
|
|
# channel_sdk.py is byte-compared with the published SDK in sdk-contract.
|
|
run: bandit -q -r . -x ./tests,./channel_sdk.py
|