Skip to content

Support Empire for system-wide deployment #179

Support Empire for system-wide deployment

Support Empire for system-wide deployment #179

Workflow file for this run

name: Lint and Test
on:
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: psf/black@24.4.2
- name: Run ruff
run: |
pip install ruff==0.5.3
ruff check .
matrix-prep-config:
runs-on: ubuntu-latest
steps:
- id: release
if: ${{ startsWith(github.head_ref, 'release/') || contains( github.event.pull_request.labels.*.name, 'run-all-versions') }}
run: |
echo "config={\"python-version\": [\"3.10\", \"3.11\", \"3.12\"]}" >> $GITHUB_OUTPUT
- id: not-release
if: ${{ !startsWith(github.head_ref, 'release/') }}
run: |
echo "config={\"python-version\": [\"3.10\", \"3.12\"]}" >> $GITHUB_OUTPUT
outputs:
config: ${{ steps.release.outputs.config || steps.not-release.outputs.config }}
test:
needs:
- matrix-prep-config
- lint
timeout-minutes: 30
runs-on: ubuntu-latest
name: Test Python ${{ matrix.python-version }}
strategy:
matrix: ${{ fromJson(needs.matrix-prep-config.outputs.config) }}
steps:
- uses: actions/checkout@v4
if: ${{ endsWith(github.repository, 'Empire') }}
with:
submodules: 'recursive'
# token is only needed in sponsors repo because of private submodules
# don't use token in public repo because prs from forks cannot access secrets
- uses: actions/checkout@v4
if: ${{ endsWith(github.repository, 'Empire-Sponsors') }}
with:
submodules: 'recursive'
token: ${{ secrets.RELEASE_TOKEN }}
- name: Install Poetry
run: |
curl -sL https://install.python-poetry.org | python - -y
# Poetry cache depends on OS, Python version and Poetry version.
# https://gist.github.com/gh640/233a6daf68e9e937115371c0ecd39c61
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'poetry'
- name: Set up MySQL
run: |
sudo systemctl start mysql
mysql -u root -proot -e "CREATE USER IF NOT EXISTS 'empire_user'@'localhost' IDENTIFIED BY 'empire_password';" || true
mysql -u root -proot -e "GRANT ALL PRIVILEGES ON *.* TO 'empire_user'@'localhost' WITH GRANT OPTION;" || true
mysql -u root -proot -e "FLUSH PRIVILEGES;" || true
- name: Install dependencies
run: |
poetry env use ${{ matrix.python-version }}
poetry install
- name: Run test suite - mysql
run: |
set -o pipefail
if [ "${{ matrix.python-version }}" = "3.12" ]; then
DATABASE_USE=mysql poetry run pytest -v --runslow --cov=empire/server --junitxml=pytest.xml --cov-report=term-missing:skip-covered . | tee pytest-coverage.txt
else
DATABASE_USE=mysql poetry run pytest -v --runslow .
fi
- name: Run test suite - sqlite
if: ${{ startsWith(github.head_ref, 'release/') || contains(github.event.pull_request.labels.*.name, 'test-sqlite') }}
run: |
DATABASE_USE=sqlite poetry run pytest . -v --runslow
- name: Pytest coverage comment
if: ${{ matrix.python-version == '3.12' }}
uses: MishaKav/pytest-coverage-comment@v1.1.53
with:
pytest-coverage-path: ./pytest-coverage.txt
junitxml-path: ./pytest.xml
test_image:
# To save CI time, only run these tests on the release PRs
if: ${{ startsWith(github.head_ref, 'release/') || contains( github.event.pull_request.labels.*.name, 'docker') }}
timeout-minutes: 30
runs-on: ubuntu-latest
name: Test Docker Image
steps:
- uses: actions/checkout@v4
with:
submodules: 'recursive'
token: ${{ secrets.RELEASE_TOKEN }}
# For the sponsors repo, this is a sort of hack to get around the fact that
# the docker image fails on ./ps-empire sync-starkiller because the repo is private.
- name: Rewrite Starkiller
run: |
if [ ${{ endswith(github.repository, 'Empire-Sponsors') }} ]; then
sed -i 's|git@github.com:BC-SECURITY/Starkiller-Sponsors.git|https://github.com/BC-SECURITY/Starkiller.git|g' empire/server/config.yaml
sed -i 's|ref: sponsors-main|ref: main|g' empire/server/config.yaml
fi
- name: Build docker image
run: docker compose -f .github/docker-compose.yml build
- name: Run tests on docker image
run: docker compose -f .github/docker-compose.yml run test
- name: run structure tests docker
uses: plexsystems/container-structure-test-action@v0.3.0
with:
image: bcsecurity/empire-test:latest
config: .github/cst-config-docker.yaml
test_install_script:
needs: test
timeout-minutes: 30
runs-on: ubuntu-latest
name: Test Install Script
strategy:
matrix:
# Because the box runs out of disk space, we can't run all tests on a single docker compose build.
images:
- ['debian10', 'debian11', 'debian12']
- ['ubuntu2004', 'ubuntu2204']
- ['kalirolling'] # 'parrotrolling'
# Parrot disabled for now because the apt repo is having some slowness issues.
# Install is running up way too many minutes.
steps:
- uses: actions/checkout@v4
with:
submodules: 'recursive'
depth: 0
# To save CI time, only run these tests when the install script or deps changed
- name: Get changed files using defaults
id: changed-files
uses: tj-actions/changed-files@v45.0.4
- name: Build images
if: contains(steps.changed-files.outputs.modified_files, 'setup/install.sh') || contains(steps.changed-files.outputs.modified_files, 'poetry.lock')
run: docker compose -f .github/install_tests/docker-compose-install-tests.yml build --parallel ${{ join(matrix.images, ' ') }}
- name: run install tests
if: contains(steps.changed-files.outputs.modified_files, 'setup/install.sh') || contains(steps.changed-files.outputs.modified_files, 'poetry.lock')
# Using a script instead of prepackaged action because composite actions can't uses
# a matrix and this is way simpler to read.
run: |
curl -LO https://storage.googleapis.com/container-structure-test/latest/container-structure-test-linux-amd64 && \
chmod +x container-structure-test-linux-amd64 && \
mkdir -p $HOME/bin && \
export PATH=$PATH:$HOME/bin && \
mv container-structure-test-linux-amd64 $HOME/bin/container-structure-test
./.github/install_tests/run-all-cst.sh ${{ join(matrix.images, ' ') }}