Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/actions/dockerhub-login/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: login to Dockerhub (to prevent image pull trottling)
runs:
using: composite
steps:
- name: docker login
run: |
docker login -u "$DOCKERHUB_USERNAME" --password-stdin <<< "$DOCKERHUB_PASSWORD" || echo "::warning::docker-login failed, ignoring"
shell: bash
18 changes: 18 additions & 0 deletions .github/actions/setup-semantic-release/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: setup semantic-release with plugins
runs:
using: composite
steps:
- uses: actions/setup-node@v5
id: setup-node
- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-npm-${{ steps.setup-node.node-version }}
- shell: bash
run: |
npm i -g \
semantic-release \
@semantic-release/exec \
@semantic-release/git \
@semantic-release/changelog \
@google/semantic-release-replace-plugin
51 changes: 51 additions & 0 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Setup base (python, pip cache, tox)
inputs:
python:
description: "Python version to use"
required: true
type: string
default: 3.12
outputs:
'python-version':
value: ${{ steps.python.outputs.python-version }}
runs:
using: "composite"
steps:
- name: pip cache
uses: actions/cache@v4
with:
path: |
~/.cache/pip
key: ${{ runner.os }}-pip-${{ inputs.python }}

- name: Cargo cache
uses: actions/cache/@v4
with:
path: "~/.cargo"
key: ${{ runner.os }}-cargo

- name: Poetry cache
uses: actions/cache/@v4
with:
path: "~/.cache/pypoetry"
key: ${{ runner.os }}-poetry-${{ inputs.python }}
restore-keys: |
${{ runner.os }}-poetry-

- uses: actions/setup-python@v6
id: python
with:
python-version: ${{ inputs.python }}

- name: upgrade pip and install tox
shell: bash
run: |
python -m pip -q install --upgrade pip "setuptools==65.6.2"
pip -q install "tox<4" tox-gh-actions

- name: install Rust and Poetry
shell: bash
run : |
curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain stable --profile minimal
source "$HOME/.cargo/env"
pip -q install poetry>=1.2.0
106 changes: 85 additions & 21 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,31 +1,95 @@
name: Build
on:
pull_request:
schedule:
- cron: "0 0 * * 0"
name: CI & Release

# Requires secrets:
# DOCKERHUB_USERNAME, DOCKERHUB_PASSWORD -- optional (for seamless pulls)
# GITHUB_TOKEN -- implicitly injected
# POETRY_PYPI_TOKEN_PYPI -- Pypi token, required for release
# POETRY_PYPI_TOKEN_TESTPYPI -- testpypi token, for CI debugging

on:
# NOTE: Release job includes extra guardrails (see job condition below)
# Without them, only linting and testing run
pull_request:
push:
branches:
- "master"
- "ci/**" # CI debugging branches
#- "v*.*" # optional: support for independent major release branches (e.g., 2.x, 3.x)
jobs:
build:
runs-on: ${{ matrix.os }}
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: ./.github/actions/setup
- name: Lint
id: lint
run: tox -e lint
continue-on-error: true
- name: Emit warning if lint failed
if: ${{ steps.lint.outcome != 'success' }}
run: echo "::warning::Linter failure suppressed (continue-on-error=true)"
test:
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest ]
python: ["3.12"]
include:
- python: "3.12"
tox_env: "lint"
python:
- "3.12"
- "3.11"
- "3.10"
- "3.9.14"
- "3.8"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
- uses: actions/checkout@v5
- uses: ./.github/actions/setup
with:
python-version: ${{ matrix.python }}
- name: Install tox
run: |
python -m pip install --upgrade pip setuptools
pip install tox
python: ${{ matrix.python }}
- name: Test
run: |
tox -e ${{ matrix.tox_env }}
run: tox
smoketest:
runs-on: ubuntu-latest
needs: [ 'lint','test' ]
steps:
- uses: actions/checkout@v5
- name: dockerhub login (for seamless docker pulling)
uses: ./.github/actions/dockerhub-login
env:
DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }}
DOCKERHUB_USERNAME: ${{ vars.DOCKERHUB_USERNAME }}
continue-on-error: true
- id: setup
uses: ./.github/actions/setup

- run: poetry build
- run: ci/run_tests.sh
env:
SMOKETEST_DOCKER_IMAGE: python:${{ steps.setup.outputs.python-version }}
release:

# NOTE: release is allowed only on selected branches
# NOTE: publishing target (prod or testpypi) is derived as PYPI_PUBLISH_REPO below
# full example:
# if: ( github.ref_name == 'master' || startsWith(github.ref_name, 'ci/') || startsWith(github.ref_name,'v') )
if: github.ref_name == 'master'

needs: ['smoketest','lint','test']
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: ./.github/actions/setup-semantic-release # node+semantic-release
- uses: ./.github/actions/setup # poetry
- name: configure poetry repos
run: |
poetry config repositories.pypi https://upload.pypi.org/legacy/
poetry config repositories.testpypi https://test.pypi.org/legacy/
- run: semantic-release --branches ${{ github.ref_name }}
env:
GIT_AUTHOR_NAME: appland-release
GIT_AUTHOR_EMAIL: release@app.land
GIT_COMMITTER_NAME: appland-release
GIT_COMMITTER_EMAIL: release@app.land
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.POETRY_PYPI_TOKEN_PYPI }}
POETRY_PYPI_TOKEN_TESTPYPI: ${{ secrets.POETRY_PYPI_TOKEN_TESTPYPI }}
PYPI_PUBLISH_REPO: ${{ github.ref == 'refs/heads/master' && 'pypi' || 'testpypi' }}
2 changes: 1 addition & 1 deletion .releaserc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ plugins:
- CHANGELOG.md
- pyproject.toml
- - '@semantic-release/exec'
- publishCmd: poetry publish --build
- publishCmd: "poetry publish --build -r <%= process.env.PYPI_PUBLISH_REPO ? process.env.PYPI_PUBLISH_REPO : 'pypi' %>"
5 changes: 4 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ python:
- "3.9.14"
- "3.8"

# Travis CI disabled in October 2025; this file is kept temporary for reference and possibility of rollback; can be deleted safely after migration
if: false

# https://github.com/travis-ci/travis-ci/issues/1147#issuecomment-441393807
if: type != push OR branch = master OR branch =~ /^v\d+\.\d+(\.\d+)?(-\S*)?$/
#if: type != push OR branch = master OR branch =~ /^v\d+\.\d+(\.\d+)?(-\S*)?$/

before_install: |
curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain stable --profile minimal
Expand Down
4 changes: 3 additions & 1 deletion ci/run_tests.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#!/usr/bin/env bash

SMOKETEST_DOCKER_IMAGE=${SMOKETEST_DOCKER_IMAGE:-"python:3.11"}

set -x
t=$([ -t 0 ] && echo 't')
docker run -q -i${t} --rm\
-v $PWD/dist:/dist -v $PWD/_appmap/test/data/unittest:/_appmap/test/data/unittest\
-v $PWD/ci:/ci\
-w /tmp\
-v $PWD/ci/readonly-mount-appmap.log:/tmp/appmap.log:ro\
python:3.11 bash -ce "${@:-/ci/smoketest.sh; /ci/test_pipenv.sh; /ci/test_poetry.sh}"
$SMOKETEST_DOCKER_IMAGE bash -ce "${@:-/ci/smoketest.sh; /ci/test_pipenv.sh; /ci/test_poetry.sh}"
15 changes: 13 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
[tox]
isolated_build = true

# The *-web environments test the latest versions of Django and Flask with the full test suite. For
# older version of the web frameworks, just run the tests that are specific to them.
envlist = py3{10,11,12}-{django5}, py3{8,9,10,11,12}-{web,django3,django4,flask2,sqlalchemy1},lint

# Default envlist is only for matrix testing. Linter and vendoring should be called explicitly
envlist = py3{10,11,12}-{django5}, py3{8,9,10,11,12}-{web,django3,django4,flask2,sqlalchemy1}

[gh-actions]
python =
3.8: py38
3.9: py39
3.10: py310
3.11: py311
3.12: py312

[web-deps]
deps=
Expand Down Expand Up @@ -54,4 +65,4 @@ deps = vendoring
commands =
poetry run vendoring {posargs:sync}
# We don't need the .pyi files vendoring generates
python -c 'from pathlib import Path; all(map(Path.unlink, Path("vendor").rglob("*.pyi")))'
python -c 'from pathlib import Path; all(map(Path.unlink, Path("vendor").rglob("*.pyi")))'
Loading