diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..95f05e2 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,102 @@ +name: CI +on: + push: + branches: + - main + pull_request: + branches: + - main + schedule: + - cron: '0 17 * * *' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +permissions: + contents: read + pull-requests: read + +jobs: + lint: + runs-on: [self-hosted, trpc-python-ci] + timeout-minutes: 15 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get changed Python files + id: changed + run: | + if [ "${{ github.event_name }}" = "pull_request" ]; then + FILES=$(git diff --name-only --diff-filter=ACM origin/${{ github.base_ref }}...HEAD -- '*.py' | grep '^trpc_sdk/' || true) + else + FILES=$(git diff --name-only --diff-filter=ACM HEAD~1...HEAD -- '*.py' | grep '^trpc_sdk/' || true) + fi + if [ -z "$FILES" ]; then + echo "has_files=false" >> "$GITHUB_OUTPUT" + else + echo "has_files=true" >> "$GITHUB_OUTPUT" + echo "$FILES" > "$RUNNER_TEMP/changed_py_files.txt" + echo "Changed Python files:" + echo "$FILES" + fi + + - name: Check formatting with YAPF + if: steps.changed.outputs.has_files == 'true' + run: | + FILES=$(cat "$RUNNER_TEMP/changed_py_files.txt" | tr '\n' ' ') + diff_output=$(yapf --diff $FILES) || true + if [ -n "$diff_output" ]; then + echo "$diff_output" + echo "::error::Code formatting check failed for changed files. Run 'yapf -i ' to fix." + exit 1 + fi + + - name: Lint with flake8 + if: steps.changed.outputs.has_files == 'true' + run: | + FILES=$(cat "$RUNNER_TEMP/changed_py_files.txt" | tr '\n' ' ') + flake8 $FILES + + test: + runs-on: [self-hosted, trpc-python-ci] + timeout-minutes: 20 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install package and dependencies + run: | + pip install -r requirements-test.txt + + - name: Run tests with coverage + # run: pytest --cov=trpc_sdk --cov-report=xml --cov-report=term tests/ + run: pytest --cov=trpc_sdk --cov-report=xml --cov-report=term --cov-fail-under=80 tests/ + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v4 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + file: coverage.xml + + build: + runs-on: [self-hosted, trpc-python-ci] + timeout-minutes: 15 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Build package + run: | + pip install build + python -m build + + - name: Verify package + run: | + pip install dist/*.whl + python -c "import trpc_sdk; print('Import OK')" diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml new file mode 100644 index 0000000..9b611a1 --- /dev/null +++ b/.github/workflows/cla.yml @@ -0,0 +1,31 @@ +name: "CLA Assistant" +on: + issue_comment: + types: [created] + pull_request_target: + types: [opened, synchronize, reopened] + +# explicitly configure permissions, in case your GITHUB_TOKEN workflow permissions are set to read-only in repository settings +permissions: + actions: write + contents: write + pull-requests: write + statuses: write + +jobs: + CLAAssistant: + runs-on: ubuntu-latest + steps: + - name: "CLA Assistant" + if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' + uses: contributor-assistant/github-action@v2.3.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PERSONAL_ACCESS_TOKEN: ${{ secrets.CLA_DATABASE_ACCESS_TOKEN }} + with: + remote-organization-name: trpc-group + remote-repository-name: cla-database + path-to-signatures: 'signatures/${{ github.event.repository.name }}-${{ github.repository_id }}/cla.json' + path-to-document: 'https://github.com/trpc-group/cla-database/blob/main/Tencent-Contributor-License-Agreement.md' + # branch should not be protected + branch: 'main' diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..2a97f80 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,54 @@ +name: Docs + +on: + push: + branches: + - main + paths: + - "docs/mkdocs/**" + - "mkdocs.yml" + - ".github/workflows/docs.yml" + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install MkDocs + run: python -m pip install --upgrade pip mkdocs + + - name: Build documentation + run: mkdocs build + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: site + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..7ad4a54 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,89 @@ +name: Auto Release when Tag +on: + push: + tags: + - 'v*' + - 'test/v*' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + +permissions: + contents: read + +jobs: + release: + runs-on: [self-hosted, trpc-python-ci] + timeout-minutes: 30 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install release dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements-test.txt + pip install build twine flake8 yapf + + - name: Validate tag version + run: | + TAG_VERSION="${GITHUB_REF_NAME#test/v}" + TAG_VERSION="${TAG_VERSION#v}" + PACKAGE_VERSION=$(python -c "from trpc_sdk.version import __version__; print(__version__)") + if [ "$TAG_VERSION" != "$PACKAGE_VERSION" ]; then + echo "::error::Tag version '$TAG_VERSION' does not match package version '$PACKAGE_VERSION'." + exit 1 + fi + + - name: Get changed Python files + id: changed + run: | + FILES=$(git diff --name-only --diff-filter=ACM HEAD~1...HEAD -- '*.py' | grep '^trpc_sdk/' || true) + if [ -z "$FILES" ]; then + echo "has_files=false" >> "$GITHUB_OUTPUT" + else + echo "has_files=true" >> "$GITHUB_OUTPUT" + echo "$FILES" > "$RUNNER_TEMP/changed_py_files.txt" + echo "Changed Python files:" + echo "$FILES" + fi + + - name: Check formatting with YAPF + if: steps.changed.outputs.has_files == 'true' + run: | + FILES=$(cat "$RUNNER_TEMP/changed_py_files.txt" | tr '\n' ' ') + diff_output=$(yapf --diff $FILES) || true + if [ -n "$diff_output" ]; then + echo "$diff_output" + echo "::error::Code formatting check failed for changed files. Run 'yapf -i ' to fix." + exit 1 + fi + + - name: Lint with flake8 + if: steps.changed.outputs.has_files == 'true' + run: | + FILES=$(cat "$RUNNER_TEMP/changed_py_files.txt" | tr '\n' ' ') + flake8 $FILES + + - name: Run tests with coverage + run: | + pytest --cov=trpc_sdk --cov-report=xml --cov-report=term --cov-fail-under=80 tests/ + + - name: Build package + run: | + python -m build + + - name: Check package + run: | + python -m twine check dist/* + + - name: Publish to PyPI + if: startsWith(github.ref, 'refs/tags/v') + run: | + python -m twine upload dist/* + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} \ No newline at end of file