From b242507965fc1772d453c37eb12c7d00d81c074a Mon Sep 17 00:00:00 2001 From: RespectTHz Date: Sun, 5 Jul 2026 05:28:54 +0700 Subject: [PATCH 1/6] Add GitHub Actions workflow for Python package with Conda This workflow sets up a Python package build using Conda on Ubuntu, installs dependencies, lints the code with flake8, and runs tests with pytest. --- .github/workflows/python-package-conda.yml | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/python-package-conda.yml diff --git a/.github/workflows/python-package-conda.yml b/.github/workflows/python-package-conda.yml new file mode 100644 index 00000000..f3586044 --- /dev/null +++ b/.github/workflows/python-package-conda.yml @@ -0,0 +1,34 @@ +name: Python Package using Conda + +on: [push] + +jobs: + build-linux: + runs-on: ubuntu-latest + strategy: + max-parallel: 5 + + steps: + - uses: actions/checkout@v4 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: '3.10' + - name: Add conda to system path + run: | + # $CONDA is an environment variable pointing to the root of the miniconda directory + echo $CONDA/bin >> $GITHUB_PATH + - name: Install dependencies + run: | + conda env update --file environment.yml --name base + - name: Lint with flake8 + run: | + conda install flake8 + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Test with pytest + run: | + conda install pytest + pytest From 3225500a4bcab30ece50e95bf6a5e841d1157703 Mon Sep 17 00:00:00 2001 From: RespectTHz Date: Wed, 8 Jul 2026 14:52:24 +0700 Subject: [PATCH 2/6] Add actions/cache@v3 for faster runs, Python version matrix, and coverage reporting --- .github/workflows/python-package-conda.yml | 27 +++++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/.github/workflows/python-package-conda.yml b/.github/workflows/python-package-conda.yml index f3586044..3ef871d2 100644 --- a/.github/workflows/python-package-conda.yml +++ b/.github/workflows/python-package-conda.yml @@ -1,26 +1,40 @@ name: Python Package using Conda -on: [push] +on: [push, pull_request] jobs: build-linux: runs-on: ubuntu-latest strategy: max-parallel: 5 + matrix: + python-version: ['3.9', '3.10', '3.11'] steps: - uses: actions/checkout@v4 - - name: Set up Python 3.10 - uses: actions/setup-python@v3 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 with: - python-version: '3.10' + python-version: ${{ matrix.python-version }} + + - name: Cache Conda packages + uses: actions/cache@v3 + with: + path: ~/.conda/pkgs + key: ${{ runner.os }}-conda-${{ hashFiles('**/environment.yml') }} + restore-keys: | + ${{ runner.os }}-conda- + - name: Add conda to system path run: | # $CONDA is an environment variable pointing to the root of the miniconda directory echo $CONDA/bin >> $GITHUB_PATH + - name: Install dependencies run: | conda env update --file environment.yml --name base + - name: Lint with flake8 run: | conda install flake8 @@ -28,7 +42,8 @@ jobs: flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Test with pytest run: | - conda install pytest - pytest + conda install pytest pytest-cov + pytest --cov=braintree_python From 01092a08ec95f9f5d46deeeded3185bf7c4d81c4 Mon Sep 17 00:00:00 2001 From: RespectTHz Date: Wed, 8 Jul 2026 14:57:10 +0700 Subject: [PATCH 3/6] Add concurrency control, verification steps, and comprehensive error handling --- .github/workflows/python-package-conda.yml | 99 +++++++++++++++++++--- 1 file changed, 85 insertions(+), 14 deletions(-) diff --git a/.github/workflows/python-package-conda.yml b/.github/workflows/python-package-conda.yml index 3ef871d2..0c2f873b 100644 --- a/.github/workflows/python-package-conda.yml +++ b/.github/workflows/python-package-conda.yml @@ -2,10 +2,16 @@ name: Python Package using Conda on: [push, pull_request] +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build-linux: runs-on: ubuntu-latest + timeout-minutes: 30 strategy: + fail-fast: false max-parallel: 5 matrix: python-version: ['3.9', '3.10', '3.11'] @@ -13,37 +19,102 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + - name: Setup Miniconda + uses: conda-incubator/setup-miniconda@v2 with: + miniconda-version: latest python-version: ${{ matrix.python-version }} + channels: conda-forge,defaults + auto-activate-base: false + activate-environment: braintree - name: Cache Conda packages uses: actions/cache@v3 with: - path: ~/.conda/pkgs - key: ${{ runner.os }}-conda-${{ hashFiles('**/environment.yml') }} + path: ~/miniconda3/pkgs + key: ${{ runner.os }}-conda-${{ matrix.python-version }}-${{ hashFiles('environment.yml') }} restore-keys: | + ${{ runner.os }}-conda-${{ matrix.python-version }}- ${{ runner.os }}-conda- - - name: Add conda to system path + - name: Install dependencies + shell: bash -l {0} run: | - # $CONDA is an environment variable pointing to the root of the miniconda directory - echo $CONDA/bin >> $GITHUB_PATH + echo "Installing dependencies from environment.yml..." + conda env update --file environment.yml --name braintree + if [ $? -ne 0 ]; then + echo "❌ Failed to install dependencies" + exit 1 + fi + echo "✅ Dependencies installed successfully" + conda list - - name: Install dependencies + - name: Install and verify flake8 + shell: bash -l {0} run: | - conda env update --file environment.yml --name base + echo "Installing flake8..." + conda install -c conda-forge flake8 -y + if [ $? -ne 0 ]; then + echo "❌ Failed to install flake8" + exit 1 + fi + flake8 --version + if [ $? -ne 0 ]; then + echo "❌ flake8 verification failed" + exit 1 + fi + echo "✅ flake8 installed and verified" - name: Lint with flake8 + shell: bash -l {0} run: | - conda install flake8 - # stop the build if there are Python syntax errors or undefined names + echo "Running flake8 checks..." + # Check for syntax errors and undefined names flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + if [ $? -ne 0 ]; then + echo "❌ Syntax errors or undefined names found" + exit 1 + fi + echo "✅ Syntax check passed" + + # Run with warnings (exit-zero mode) + echo "Running flake8 with warnings..." flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + echo "✅ Lint check completed" + + - name: Install and verify pytest + shell: bash -l {0} + run: | + echo "Installing pytest and pytest-cov..." + conda install -c conda-forge pytest pytest-cov -y + if [ $? -ne 0 ]; then + echo "❌ Failed to install pytest" + exit 1 + fi + pytest --version + if [ $? -ne 0 ]; then + echo "❌ pytest verification failed" + exit 1 + fi + echo "✅ pytest installed and verified" - name: Test with pytest + shell: bash -l {0} run: | - conda install pytest pytest-cov - pytest --cov=braintree_python + echo "Running pytest with coverage..." + pytest --cov=braintree_python --cov-report=xml --cov-report=term --cov-fail-under=70 -v + if [ $? -ne 0 ]; then + echo "❌ Tests failed or coverage threshold not met" + exit 1 + fi + echo "✅ All tests passed" + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v3 + if: always() + with: + files: ./coverage.xml + flags: unittests + name: codecov-umbrella-${{ matrix.python-version }} + fail_ci_if_error: false + verbose: true From f66e611dcdb3f97bd39b6fa03ffe5928872c9f0a Mon Sep 17 00:00:00 2001 From: RespectTHz Date: Wed, 8 Jul 2026 14:58:21 +0700 Subject: [PATCH 4/6] Remove cache step from workflow --- .github/workflows/python-package-conda.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/python-package-conda.yml b/.github/workflows/python-package-conda.yml index 0c2f873b..16d2c76e 100644 --- a/.github/workflows/python-package-conda.yml +++ b/.github/workflows/python-package-conda.yml @@ -28,15 +28,6 @@ jobs: auto-activate-base: false activate-environment: braintree - - name: Cache Conda packages - uses: actions/cache@v3 - with: - path: ~/miniconda3/pkgs - key: ${{ runner.os }}-conda-${{ matrix.python-version }}-${{ hashFiles('environment.yml') }} - restore-keys: | - ${{ runner.os }}-conda-${{ matrix.python-version }}- - ${{ runner.os }}-conda- - - name: Install dependencies shell: bash -l {0} run: | From 695be588711662b4c261de6bc0cf47d2bb6b8ad5 Mon Sep 17 00:00:00 2001 From: RespectTHz Date: Wed, 8 Jul 2026 15:06:55 +0700 Subject: [PATCH 5/6] Add security checks with bandit and safety for vulnerability scanning --- .github/workflows/python-package-conda.yml | 66 ++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/.github/workflows/python-package-conda.yml b/.github/workflows/python-package-conda.yml index 16d2c76e..f890583c 100644 --- a/.github/workflows/python-package-conda.yml +++ b/.github/workflows/python-package-conda.yml @@ -40,6 +40,62 @@ jobs: echo "✅ Dependencies installed successfully" conda list + - name: Install and verify bandit + shell: bash -l {0} + run: | + echo "Installing bandit for security scanning..." + conda install -c conda-forge bandit -y + if [ $? -ne 0 ]; then + echo "❌ Failed to install bandit" + exit 1 + fi + bandit --version + if [ $? -ne 0 ]; then + echo "❌ bandit verification failed" + exit 1 + fi + echo "✅ bandit installed and verified" + + - name: Security check with bandit + shell: bash -l {0} + run: | + echo "Running bandit security scan..." + bandit -r . -f json -o bandit-report.json + bandit -r . -f txt + if [ $? -ne 0 ]; then + echo "⚠️ Security issues detected (see report above)" + else + echo "✅ No security issues found" + fi + + - name: Install and verify safety + shell: bash -l {0} + run: | + echo "Installing safety for dependency vulnerability scanning..." + pip install safety + if [ $? -ne 0 ]; then + echo "❌ Failed to install safety" + exit 1 + fi + safety --version + if [ $? -ne 0 ]; then + echo "❌ safety verification failed" + exit 1 + fi + echo "✅ safety installed and verified" + + - name: Dependency vulnerability check with safety + shell: bash -l {0} + run: | + echo "Running safety dependency vulnerability scan..." + safety check --json > safety-report.json || true + safety check + if [ $? -ne 0 ]; then + echo "⚠️ Vulnerable dependencies detected (see report above)" + else + echo "✅ No vulnerable dependencies found" + fi + - name: Install and verify flake8 shell: bash -l {0} run: | @@ -109,3 +165,13 @@ jobs: name: codecov-umbrella-${{ matrix.python-version }} fail_ci_if_error: false verbose: true + + - name: Upload security reports + uses: actions/upload-artifact@v3 + if: always() + with: + name: security-reports-py${{ matrix.python-version }} + path: | + bandit-report.json + safety-report.json + retention-days: 30 From 2a7fc897757a151fc4d21414a48897806ddd37ae Mon Sep 17 00:00:00 2001 From: RespectTHz Date: Wed, 8 Jul 2026 15:08:26 +0700 Subject: [PATCH 6/6] Add Python 3.8 legacy support to test matrix --- .github/workflows/python-package-conda.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package-conda.yml b/.github/workflows/python-package-conda.yml index f890583c..d79a7e35 100644 --- a/.github/workflows/python-package-conda.yml +++ b/.github/workflows/python-package-conda.yml @@ -14,7 +14,7 @@ jobs: fail-fast: false max-parallel: 5 matrix: - python-version: ['3.9', '3.10', '3.11'] + python-version: ['3.8', '3.9', '3.10', '3.11'] steps: - uses: actions/checkout@v4