From 339e8343d2f5a9d478f0c8c78dad127498f9ebe0 Mon Sep 17 00:00:00 2001 From: Luke Tainton Date: Wed, 1 Jan 2025 00:17:19 +0100 Subject: [PATCH] chore(ci): migrate SOT to Gitea (#429) Reviewed-on: https://git.tainton.uk/public/webexmemebot/pulls/429 --- .archive/.github/CODEOWNERS | 1 + {.github => .archive/.github}/dependabot.yml | 0 {.github => .archive/.github}/renovate.json | 0 .../.github}/workflows-old/release.yml | 0 .archive/.github/workflows/ci.yml | 20 +++ .archive/.github/workflows/release.yml | 26 ++++ .gitea/CODEOWNERS | 1 + .gitea/workflows/ci.yml | 74 ++++++++++ .gitea/workflows/release.yml | 133 ++++++++++++++++++ renovate.json | 42 ++++++ sonar-project.properties | 4 +- 11 files changed, 299 insertions(+), 2 deletions(-) create mode 100644 .archive/.github/CODEOWNERS rename {.github => .archive/.github}/dependabot.yml (100%) rename {.github => .archive/.github}/renovate.json (100%) rename {.github => .archive/.github}/workflows-old/release.yml (100%) create mode 100644 .archive/.github/workflows/ci.yml create mode 100644 .archive/.github/workflows/release.yml create mode 100644 .gitea/CODEOWNERS create mode 100644 .gitea/workflows/ci.yml create mode 100644 .gitea/workflows/release.yml create mode 100644 renovate.json diff --git a/.archive/.github/CODEOWNERS b/.archive/.github/CODEOWNERS new file mode 100644 index 0000000..55e6153 --- /dev/null +++ b/.archive/.github/CODEOWNERS @@ -0,0 +1 @@ +* @luketainton diff --git a/.github/dependabot.yml b/.archive/.github/dependabot.yml similarity index 100% rename from .github/dependabot.yml rename to .archive/.github/dependabot.yml diff --git a/.github/renovate.json b/.archive/.github/renovate.json similarity index 100% rename from .github/renovate.json rename to .archive/.github/renovate.json diff --git a/.github/workflows-old/release.yml b/.archive/.github/workflows-old/release.yml similarity index 100% rename from .github/workflows-old/release.yml rename to .archive/.github/workflows-old/release.yml diff --git a/.archive/.github/workflows/ci.yml b/.archive/.github/workflows/ci.yml new file mode 100644 index 0000000..2f2c77d --- /dev/null +++ b/.archive/.github/workflows/ci.yml @@ -0,0 +1,20 @@ +name: CI +on: + pull_request: + types: [opened, synchronize, reopened] + paths-ignore: + - "README.md" + - "LICENSE.md" + - ".gitignore" + - ".github/CODEOWNERS" + - ".github/renovate.json" + - ".github/dependabot.yml" + +jobs: + ci: + uses: luketainton/gha-workflows/.github/workflows/ci-python-poetry-with-docker.yml@main + with: + python-version: "3.13" + secrets: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} diff --git a/.archive/.github/workflows/release.yml b/.archive/.github/workflows/release.yml new file mode 100644 index 0000000..6d5a1ca --- /dev/null +++ b/.archive/.github/workflows/release.yml @@ -0,0 +1,26 @@ +name: Release +on: + workflow_dispatch: + schedule: + - cron: "0 9 * * 0" + +jobs: + test: + uses: luketainton/gha-workflows/.github/workflows/ci-python-poetry-with-docker.yml@main + with: + python-version: "3.13" + secrets: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + + create_release: + name: Create Release + uses: luketainton/gha-workflows/.github/workflows/create-release.yml@main + + create_docker: + name: Create Docker Image + needs: create_release + if: ${{ needs.create_release.outputs.success == 'true' }} + uses: luketainton/gha-workflows/.github/workflows/build-push-attest-docker.yml@main + with: + release: ${{ needs.create_release.outputs.release_name }} diff --git a/.gitea/CODEOWNERS b/.gitea/CODEOWNERS new file mode 100644 index 0000000..e286c1e --- /dev/null +++ b/.gitea/CODEOWNERS @@ -0,0 +1 @@ +* @luke diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml new file mode 100644 index 0000000..8d05156 --- /dev/null +++ b/.gitea/workflows/ci.yml @@ -0,0 +1,74 @@ +name: CI +on: + pull_request: + types: [opened, synchronize, reopened] + paths-ignore: + - "README.md" + - "LICENSE.md" + - ".gitignore" + - "renovate.json" + - ".gitea/CODEOWNERS" + - ".archive" + +jobs: + ci: + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v4.1.7 + with: + fetch-depth: 0 + + - uses: hadolint/hadolint-action@v3.1.0 + with: + dockerfile: Dockerfile + output-file: hadolint.out + format: sonarqube + no-fail: true + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "${{ vars.PYTHON_VERSION }}" + + - name: Setup Poetry + run: curl -sSL https://install.python-poetry.org | python3 - + + - name: Update PATH + run: export PATH="/root/.local/bin:$PATH" + + - name: Install dependencies + run: /root/.local/bin/poetry install + + - name: Lint + run: | + /root/.local/bin/poetry run pylint --fail-under=8 --recursive=yes --output-format=parseable --output=lintreport.txt . + cat lintreport.txt + + - name: Unit Test + run: | + /root/.local/bin/poetry run coverage run -m pytest -v --junitxml=testresults.xml + /root/.local/bin/poetry run coverage xml + sed -i 's@${{ gitea.workspace }}@/github/workspace@g' coverage.xml + + # TEMPORARY - DISABLED DUE TO GITHUB > GITEA MIGRATION + # SONARQUBE CLOUD IS CURRENTLY TIGHTLY COUPLED TO GITHUB + - name: SonarQube Cloud Scan + uses: SonarSource/sonarqube-scan-action@v4.2.1 + continue-on-error: true + env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + + - name: Snyk Vulnerability Scan + uses: snyk/actions/python-3.10@master + continue-on-error: true # To make sure that SARIF upload gets called + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + with: + args: --sarif-file-output=snyk.sarif --all-projects + + # - name: Upload result to GitHub Code Scanning + # uses: github/codeql-action/upload-sarif@v3 + # with: + # sarif_file: snyk.sarif diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..f0492e7 --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,133 @@ +name: Release +on: + schedule: + - cron: "0 9 * * 0" + +jobs: + test: + uses: https://git.tainton.uk/public/webexmemebot/src/branch/main/.gitea/workflows/ci.yml + + create_release: + runs-on: ubuntu-latest + outputs: + release_name: ${{ steps.tag_version.outputs.new_tag }} + success: ${{ steps.set_flag.outputs.success }} + steps: + - uses: actions/checkout@v4.1.7 + with: + fetch-depth: 0 + + - name: Changes since last tag + id: changes + run: | + CHANGES=$(git log $(git describe --tags --abbrev=0)..HEAD --no-merges --oneline) + echo "$CHANGES" + if [ -z "$CHANGES" ]; then echo "changes=false" >> "$GITEA_OUTPUT"; else echo "changes=true" >> "$GITEA_OUTPUT"; fi + + - name: Bump version and push tag + id: tag_version + if: steps.changes.outputs.changes == 'true' + uses: mathieudutour/github-tag-action@v6.2 + with: + github_token: ${{ gitea.token }} + default_bump: minor + # default_bump: false + + - name: Build Changelog + uses: mikepenz/release-changelog-builder-action@v4 + id: build_changelog + env: + GITHUB_TOKEN: ${{ gitea.token }} + with: + configurationJson: | + { + "pr_template": "- #{{TITLE}} ([##{{NUMBER}}](#{{URL}}))", + "empty_template": "- no changes", + "categories": [ + { + "title": "## 💬 Other", + "labels": ["type/other"] + }, + { + "title": "## 📦 Dependencies", + "labels": ["type/dependencies"] + }, + { + "title": "## 🚀 Features", + "labels": ["type/feature"] + }, + { + "title": "## 🐛 Bug Fixes", + "labels": ["type/bugfix"] + }, + ] + } + + - name: Create release + id: create_release + uses: akkuman/gitea-release-action@v1 + env: + NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18 + with: + tag: ${{ steps.tag_version.outputs.new_tag }} + name: ${{ steps.tag_version.outputs.new_tag }} + body: ${{ steps.build_changelog.outputs.changelog }} + + - name: Set success/fail flag + id: set_flag + if: steps.changes.outputs.changes == 'true' + run: if test "${{ steps.changes.outputs.changes }}" = "true"; then echo "success=true" >> "$GITHUB_OUTPUT"; else echo "success=false" >> "$GITHUB_OUTPUT"; fi + + create_docker: + name: Create Docker Image + needs: create_release + if: ${{ needs.create_release.outputs.success == 'true' }} + outputs: + success: ${{ steps.set_flag.outputs.success }} + with: + release: ${{ needs.create_release.outputs.release_name }} + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ inputs.release }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Gitea Container Registry + uses: docker/login-action@v3 + with: + registry: git.tainton.uk + username: ${{ gitea.actor }} + password: ${{ gitea.token }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: | + git.tainton.uk/${{ gitea.repository }} + tags: | + type=semver,pattern=v{{version}},value=${{ inputs.release }} + + - name: Build and push Docker image + id: push + uses: docker/build-push-action@v6 + with: + context: . + push: true + labels: ${{ steps.meta.outputs.labels }} + tags: | + git.tainton.uk/${{ gitea.repository }}:latest + git.tainton.uk/${{ gitea.repository }}:${{ inputs.release }} + + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v2 + with: + subject-name: git.tainton.uk/${{ gitea.repository }} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: true + + - name: Set success flag + id: set_flag + run: echo "success=true" >> "$GITHUB_OUTPUT" diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..c721baf --- /dev/null +++ b/renovate.json @@ -0,0 +1,42 @@ +{ + "assignAutomerge": true, + "assigneesFromCodeOwners": true, + "dependencyDashboardAutoclose": true, + "extends": [ + "config:base" + ], + "labels": [ + "type/dependencies" + ], + "packageRules": [ + { + "labels": [ + "linting" + ], + "matchPackagePatterns": [ + "black", + "pylint" + ] + }, + { + "labels": [ + "unit-tests" + ], + "matchPackagePatterns": [ + "coverage", + "pytest" + ] + } + ], + "platformCommit": true, + "rebaseWhen": "behind-base-branch", + "rollbackPrs": true, + "vulnerabilityAlerts": { + "commitMessagePrefix": "[SECURITY] ", + "enabled": true, + "labels": [ + "security" + ], + "prCreation": "immediate" + } +} diff --git a/sonar-project.properties b/sonar-project.properties index 08f2552..3e02a4c 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,8 +1,8 @@ sonar.organization=luketainton -sonar.projectKey=luketainton_webexmemebot +sonar.projectKey=luketainton_webexmemebot2 sonar.projectName=webexmemebot sonar.projectVersion=0.1.0 -sonar.python.version=3.11 +sonar.python.version=3.13 sonar.python.coverage.reportPaths=coverage.xml sonar.python.pylint.reportPaths=lintreport.txt sonar.python.xunit.reportPath=testresults.xml