feat: port to Python and package as pip-installable distribution

Replaces main.sh with the 'cli-gnome-extension-manager' distribution in a src layout, shipping both the cli-gnome-extension-manager and the older goexma command.

sync_repository keeps the three states of the shell original apart: clone when the folder is missing, pull when it is a checkout, leave it alone otherwise, so a manually installed extension is never overwritten. build_extension still moves the checkout away before make install, but into a TemporaryDirectory instead of a fixed /tmp/<name>, which removes the collision between parallel runs and cleans up on abort.

Every step passes through the exit code of the failing tool, replacing the shell chain of || exit 1; a missing gnome-extensions aborts with exit 127. The e2e suite builds a real git repository, clones it with real git and runs real make install.

Adds --extensions-dir, unit, integration and container-based e2e tests, ruff and markdown/mermaid linting, CodeQL and Dependabot, and pins the core metadata to 2.4 so twine accepts the artifacts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-14 14:41:17 +02:00
parent 59943dc029
commit ccac936015
23 changed files with 1149 additions and 72 deletions

21
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
groups:
actions:
patterns:
- "*"
- package-ecosystem: docker
directories:
- "/tests/e2e"
schedule:
interval: weekly
- package-ecosystem: pip
directory: /
schedule:
interval: weekly

80
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,80 @@
name: CI
on:
push:
pull_request:
jobs:
test-and-lint:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: "pip"
- name: Install package and tooling
shell: bash
run: |
set -euo pipefail
python -m pip install --upgrade pip
python -m pip install -e .
python -m pip install ruff
- name: Ruff (lint)
shell: bash
run: |
set -euo pipefail
ruff check .
- name: Ruff (format check)
shell: bash
run: |
set -euo pipefail
ruff format --check .
- name: Unit tests
shell: bash
run: |
set -euo pipefail
make test-unit
- name: Integration tests
shell: bash
run: |
set -euo pipefail
make test-integration
docs:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Markdown and mermaid lint
shell: bash
run: |
set -euo pipefail
make lint-docs
e2e:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@v4
- name: End-to-end tests in a container
shell: bash
run: |
set -euo pipefail
make test-e2e

43
.github/workflows/codeql.yml vendored Normal file
View File

@@ -0,0 +1,43 @@
name: CodeQL
on:
push:
pull_request:
schedule:
- cron: "27 4 * * 1"
jobs:
analyze:
name: Check security
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
security-events: write
packages: read
contents: read
strategy:
fail-fast: false
matrix:
include:
- language: actions
build-mode: none
- language: python
build-mode: none
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
queries: security-extended,security-and-quality
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{ matrix.language }}"