Support Empire for system-wide deployment #179
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, ' ') }} |