diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..3a4c94c2e --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,51 @@ +name: Release build + +on: + push: + branches: + - release/** + +jobs: + docs: + name: Build and upload Linux release and docs + runs-on: ubuntu-latest + + steps: + - name: Checkout sources + uses: actions/checkout@v2 + + - name: Build symbolicator + run: | + cargo build --release + objcopy --only-keep-debug target/release/symbolicator{,.debug} + objcopy --strip-debug --strip-unneeded target/release/symbolicator + objcopy --add-gnu-debuglink target/release/symbolicator{.debug,} + zip symbolicator-debug.zip target/release/symbolicator.debug + + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: 3.8 + + - name: Setup python dependencies + run: pip install --upgrade mkdocs mkdocs-material pygments + + - name: Build Docs + run: | + mkdocs build + touch site/.nojekyll + cd site && zip -r gh-pages . + + - name: Setup node + uses: actions/setup-node@v1 + + - name: Upload to Zeus + env: + ZEUS_HOOK_BASE: ${{ secrets.ZEUS_HOOK_BASE }} + run: | + npm install -D @zeus-ci/cli + npx zeus job update -b ${{ github.run_id }} -j ${{ github.job }} -r ${{ github.sha }} + npx zeus upload -b ${{ github.run_id }} -j ${{ github.job }} -t "application/octet-stream" -n symbolicator-Linux-x86_64 target/release/symbolicator + npx zeus upload -b ${{ github.run_id }} -j ${{ github.job }} -t "application/zip" -n symbolicator-Linux-x86_64-debug.zip symbolicator-debug.zip + npx zeus upload -b ${{ github.run_id }} -j ${{ github.job }} -t "application/zip+docs" site/gh-pages.zip + npx zeus job update --status=passed -b ${{ github.run_id }} -j ${{ github.job }} -r ${{ github.sha }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..405156274 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,137 @@ +name: CI + +on: + push: + branches: + - master + - release/** + + pull_request: + +jobs: + lints: + name: Lints + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v2 + + - name: Install python + uses: actions/setup-python@v2 + with: + python-version: 3.8 + + - name: Install python dependencies + run: pip install --upgrade black flake8 + + - name: Run Black + run: black --check tests + + - name: Run Flake8 + run: flake8 tests + + - name: Install rust stable toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + profile: minimal + components: rustfmt, clippy + override: true + + - name: Cache rust cargo artifacts + uses: swatinem/rust-cache@v1 + with: + key: ${{ github.job }} + + - name: Run cargo fmt + uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check + + - name: Run clipppy + uses: actions-rs/clippy-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + args: --all-features --workspace --tests --examples -- -D clippy::all + + unit-test: + name: Unit Tests + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v2 + + - name: Install rust stable toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + profile: minimal + override: true + + - name: Cache rust cargo artifacts + uses: swatinem/rust-cache@v1 + with: + key: ${{ github.job }} + + - name: Run cargo test + uses: actions-rs/cargo@v1 + with: + command: test + args: --workspace --all-features --locked + + integration-test: + name: Integration Tests + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v2 + + - name: Install rust stable toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + profile: minimal + override: true + + - name: Cache rust cargo artifacts + uses: swatinem/rust-cache@v1 + with: + key: ${{ github.job }} + + - name: Build rust + run: cargo build --locked + + - name: Install python + uses: actions/setup-python@v2 + with: + python-version: 3.8 + + - name: Setup python environment + run: pip install --upgrade pytest pytest-localserver requests pytest-xdist pytest-icdiff boto3 + + - name: Integration tests + env: + SENTRY_SYMBOLICATOR_GCS_CLIENT_EMAIL: ${{ secrets.SENTRY_SYMBOLICATOR_GCS_CLIENT_EMAIL }} + SENTRY_SYMBOLICATOR_GCS_PRIVATE_KEY: ${{ secrets.SENTRY_SYMBOLICATOR_GCS_PRIVATE_KEY }} + SENTRY_SYMBOLICATOR_TEST_AWS_ACCESS_KEY_ID: ${{ secrets.SENTRY_SYMBOLICATOR_TEST_AWS_ACCESS_KEY_ID }} + SENTRY_SYMBOLICATOR_TEST_AWS_SECRET_ACCESS_KEY: ${{ secrets.SENTRY_SYMBOLICATOR_TEST_AWS_SECRET_ACCESS_KEY }} + run: pytest --ci -n12 -vv tests/integration + + docs: + name: Build docs + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v2 + + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: 3.8 + + - name: Setup python dependencies + run: pip install --upgrade mkdocs mkdocs-material pygments + + - name: Build Docs + run: mkdocs build diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 6e220b269..000000000 --- a/.travis.yml +++ /dev/null @@ -1,56 +0,0 @@ -os: linux -dist: xenial -language: rust - -before_install: - - pyenv install 3.6.3 - - pyenv global 3.6.3 - -git: - depth: 1 - -branches: - only: - - master - - /^release\/[\d.]+$/ - -env: - - CXX=clang - -jobs: - include: - - name: "style check" - script: make -e style - - - name: "lint" - script: make -e lint - - - name: "test" - script: make -e test-rust - - - name: "e2e" - script: make -e test-integration - - - name: "release: linux x86_64" - if: branch ~= /^release\/[\d.]+$/ - before_script: npm install -g @zeus-ci/cli - script: - - make release - - zeus upload -t "application/octet-stream" -n symbolicator-Linux-x86_64 target/release/symbolicator - - zip symbolicator-debug.zip target/symbolicator/symbolicator.debug - - zeus upload -t "application/octet-stream" -n symbolicator-Linux-x86_64-debug.zip symbolicator-debug.zip - - - name: "release: docs" - if: branch ~= /^release\/[\d.]+$/ - before_script: npm install -g @zeus-ci/cli - script: make -e travis-upload-docs - -notifications: - webhooks: - urls: - - https://zeus.ci/hooks/53a70baa-5131-11e9-902b-0a580a282506/public/provider/travis/webhook - on_success: always - on_failure: always - on_start: always - on_cancel: always - on_error: always diff --git a/Makefile b/Makefile index 01a7a922f..9a0448040 100644 --- a/Makefile +++ b/Makefile @@ -31,13 +31,13 @@ test: test-rust test-integration .PHONY: test test-rust: - cargo test --all --all-features --locked + cargo test --workspace --all-features --locked .PHONY: test-rust test-integration: .venv/bin/python .venv/bin/pip install -U pytest pytest-localserver requests pytest-xdist pytest-icdiff boto3 cargo build --locked - @.venv/bin/pytest tests -n12 -vv + @.venv/bin/pytest $(CI_ARGS) tests/integration -n12 -vv .PHONY: test-integration # Documentation @@ -86,7 +86,7 @@ lint-python: .venv/bin/python lint-rust: @rustup component add clippy --toolchain stable 2> /dev/null - cargo +stable clippy --all-features --all --tests --examples -- -D clippy::all + cargo +stable clippy --all-features --workspace --tests --examples -- -D clippy::all .PHONY: lint-rust # Formatting diff --git a/pytest.ini b/pytest.ini index 08cd281a2..4926673ec 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,6 +1,6 @@ [pytest] addopts = -ra --tb=native --durations 5 -p no:warnings -testpaths = tests +testpaths = tests/integration markers = extra_failure_checks: Marker which can add additional failure checks to a test. It accepts the keyword argument `checks` which should be a diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 337a6238f..31d1200c4 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -25,6 +25,16 @@ session = requests.session() +@pytest.hookimpl +def pytest_addoption(parser): + parser.addoption( + "--ci", + action="store_true", + help="Indicate the tests are being run on CI, " + "this e.g. prefers to fail tests instead of skipping them.", + ) + + @pytest.hookimpl def pytest_sessionstart(session): no_fds_soft, no_fds_hard = resource.getrlimit(resource.RLIMIT_NOFILE) @@ -271,9 +281,13 @@ def fail_on_errors(): @pytest.fixture -def s3(): +def s3(pytestconfig): if not AWS_ACCESS_KEY_ID or not AWS_SECRET_ACCESS_KEY: - pytest.skip("No AWS credentials") + msg = "No AWS credentials" + if pytestconfig.getoption("ci"): + pytest.fail(msg) + else: + pytest.skip(msg) return boto3.resource( "s3", aws_access_key_id=AWS_ACCESS_KEY_ID, @@ -299,9 +313,13 @@ def s3_bucket_config(s3): @pytest.fixture -def ios_bucket_config(): +def ios_bucket_config(pytestconfig): if not GCS_PRIVATE_KEY or not GCS_CLIENT_EMAIL: - pytest.skip("No GCS credentials") + msg = "No GCS credentials" + if pytestconfig.getoption("ci"): + pytest.fail(msg) + else: + pytest.skip(msg) yield { "id": "ios", "type": "gcs",