Skip to content

Commit d0406ae

Browse files
add management command for importing an existing installation (#11)
* add management command for importing an existing installation * add integration tests for management command and adjust command also some docs * remove abc from typevar * add types for cli * add test stubs for new method * tweak documentation * adjust documentation * fix command * tweakssss * expand * add integration test job * add note about ci * add check for secret * remove check * add tests for refresh and adjust fail floor for coverage * add test for calling management command * start import section in README * remove titel * add new model method to docs * swap for coverage * pare back endpoints to ones actually used * fix types by switching account type to enum * adjust installation instructions in README * adjust formatting * change to subsections * update changelog * update changelog * update docs * update docs * adjust * adjust wording * explicit name of command
1 parent 7802aaf commit d0406ae

File tree

16 files changed

+692
-58
lines changed

16 files changed

+692
-58
lines changed

.env.example

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
TEST_ACCOUNT_NAME=
2+
TEST_ACCOUNT_TYPE=
3+
TEST_APP_ID=
4+
TEST_CLIENT_ID=
5+
TEST_INSTALLATION_ID=
6+
TEST_NAME=
7+
TEST_PRIVATE_KEY=""
8+
TEST_WEBHOOK_SECRET=""

.github/workflows/test.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,31 @@ jobs:
6565
if: ${{ contains(needs.*.result, 'failure') }}
6666
run: exit 1
6767

68+
integration:
69+
runs-on: ubuntu-latest
70+
environment: integration
71+
steps:
72+
- uses: actions/checkout@v4
73+
74+
- name: Install uv
75+
uses: astral-sh/setup-uv@v3
76+
with:
77+
enable-cache: true
78+
version: ${{ env.UV_VERSION }}
79+
80+
- name: Run tests with integration tests enabled
81+
env:
82+
TEST_ACCOUNT_NAME: ${{ vars.TEST_ACCOUNT_NAME }}
83+
TEST_ACCOUNT_TYPE: ${{ vars.TEST_ACCOUNT_TYPE }}
84+
TEST_APP_ID: ${{ vars.TEST_APP_ID }}
85+
TEST_CLIENT_ID: ${{ vars.TEST_CLIENT_ID }}
86+
TEST_INSTALLATION_ID: ${{ vars.TEST_INSTALLATION_ID }}
87+
TEST_NAME: ${{ vars.TEST_NAME }}
88+
TEST_PRIVATE_KEY: ${{ secrets.TEST_PRIVATE_KEY }}
89+
TEST_WEBHOOK_SECRET: ${{ secrets.TEST_WEBHOOK_SECRET }}
90+
run: |
91+
uv run nox --session "coverage" -- --integration
92+
6893
types:
6994
runs-on: ubuntu-latest
7095
steps:

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ and this project attempts to adhere to [Semantic Versioning](https://semver.org/
2626
- `aget_repos`/`get_repos` for retrieving all repositories accessible to an app installation.
2727
- Added `get_gh_client` model method to `Installation` model.
2828
- Added `aget_repos`/`get_repos` model method to `installation`
29+
- Added `arefresh_from_gh`/`refresh_from_gh` model methods to `Installation` model for syncing local data with GitHub.
30+
- Created a new management command namespace, `python manage.py github`, for all django-github-app management commands.
31+
- Added a new management command to `github` namespace, `python manage.py github import-app`, for importing an existing GitHub App and installation.
2932

3033
## [0.1.0]
3134

CONTRIBUTING.md

Lines changed: 96 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ We adhere to Django's Code of Conduct in all interactions and expect all contrib
2020

2121
### `Justfile`
2222

23-
The repository includes a `Justfile` that provides all common development tasks with a consistent interface. Running `just` without arguments shows all available commands and their descriptions:
23+
The repository includes a `Justfile` that provides all common development tasks with a consistent interface. Running `just` without arguments shows all available commands and their descriptions.
2424

2525
<!-- [[[cog
2626
import subprocess
@@ -70,16 +70,17 @@ The following instructions will use `uv` and assume a Unix-like operating system
7070

7171
Windows users will need to adjust commands accordingly, though the core workflow remains the same.
7272

73-
Alternatively, any Python package manager that supports installing from `pyproject.toml` ([PEP 621](https://peps.python.org/pep-0621/)) can be used. If not using `uv`, ensure you have Python installed from [python.org](https://www.python.org/).
73+
Alternatively, any Python package manager that supports installing from `pyproject.toml` ([PEP 621](https://peps.python.org/pep-0621/)) can be used. If not using `uv`, ensure you have Python installed from [python.org](https://www.python.org/) or another source such as [`pyenv`](https://github.com/pyenv/pyenv).
7474

7575
1. Fork the repository and clone it locally.
76-
2. Use `uv` too bootstrap your development environment:
7776

78-
```bash
79-
uv python install
80-
uv sync --locked
81-
# just bootstrap
82-
```
77+
2. Use `uv` to bootstrap your development environment.
78+
79+
```bash
80+
uv python install
81+
uv sync --locked
82+
# just bootstrap
83+
```
8384

8485
This will install the correct Python version, create and configure a virtual environment, and install all dependencies.
8586

@@ -101,7 +102,7 @@ uv run nox --session tests
101102
# just testall
102103
```
103104

104-
Both can be passed additional arguments that will be provided to `pytest`:
105+
Both can be passed additional arguments that will be provided to `pytest`.
105106

106107
```bash
107108
uv run nox --session test -- -v --last-failed
@@ -123,6 +124,91 @@ uv run nox --session coverage
123124

124125
All pull requests must include tests to maintain 100% coverage. Coverage configuration can be found in the `[tools.coverage.*]` sections of [`pyproject.toml`](pyproject.toml).
125126

127+
### Integration Tests
128+
129+
Integration tests in [`tests/integration`](tests/integration) verify actual interactions with GitHub's API and webhooks. These tests are skipped by default and require:
130+
131+
- A GitHub App in your account
132+
- Environment variables configured with the App's credentials
133+
134+
To enable integration tests, pass `--integration` to any test command:
135+
136+
```bash
137+
uv run nox --session test -- --integration
138+
# just test --integration
139+
```
140+
141+
#### Setting up a Test GitHub App
142+
143+
1. Create a new GitHub App.
144+
145+
- Go to GitHub Developer Settings > GitHub Apps > New GitHub App
146+
- Name: `@<username> - django-github-app tests` (must be unique on GitHub, max 34 characters)
147+
- Homepage URL: Your fork's URL (e.g., `https://github.com/<username>/django-github-app`)
148+
- Webhooks: Disable by unchecking "Active" (no webhook tests currently implemented)
149+
- Permissions:
150+
- Repository: Metadata (Read-only)
151+
- Installation: "Only on this account"
152+
153+
2. After creation, collect these values:
154+
155+
- App ID (from app settings)
156+
- Client ID (from app settings)
157+
- Private key (generate and download)
158+
- Installation ID (from URL after installing: `https://github.com/settings/installations/<ID>`)
159+
160+
3. Configure environment variables.
161+
162+
Using direnv (recommended):
163+
164+
```bash
165+
cp .env.example .env
166+
```
167+
168+
Edit the new `.env` file with the values collected above.
169+
170+
Or manually export:
171+
172+
```bash
173+
export TEST_ACCOUNT_NAME="<username>"
174+
# etc...
175+
```
176+
177+
See [`.env.example`](.env.example) for all required variables.
178+
179+
#### Setting up CI Integration Tests
180+
181+
If you want integration tests to run in CI on your fork:
182+
183+
1. Go to your fork's repository settings on GitHub
184+
185+
2. Under "Environments", create a new environment named `integration`
186+
187+
3. Add the following secrets and variables to the environment:
188+
189+
- Secrets
190+
- `TEST_PRIVATE_KEY`
191+
- `TEST_WEBHOOK_SECRET`
192+
- Variables
193+
- `TEST_ACCOUNT_NAME`
194+
- `TEST_ACCOUNT_TYPE`
195+
- `TEST_APP_ID`
196+
- `TEST_CLIENT_ID`
197+
- `TEST_INSTALLATION_ID`
198+
- `TEST_NAME`
199+
200+
> [!NOTE]
201+
> Integration tests in CI will only run with access to these environment secrets. This is a security feature - fork PRs cannot access these secrets unless explicitly granted by repository maintainers.
202+
203+
#### Security Considerations
204+
205+
The integration test setup is designed to be secure:
206+
207+
- The test GitHub App requires minimal permissions (read-only metadata access)
208+
- It's installed only on your personal account
209+
- In CI, tests run in a protected GitHub Environment with restricted secret access
210+
- Fork PRs cannot access integration test secrets (managed automatically by GitHub Actions)
211+
126212
## Linting and Formatting
127213

128214
This project enforces code quality standards using [`pre-commit`](https://github.com/pre-commit/pre-commit).
@@ -155,7 +241,7 @@ Configuration for these tools can be found in:
155241

156242
## Continuous Integration
157243

158-
This project uses GitHub Actions for CI/CD. The workflows can be found in [`.github/workflows/`](.github/workflows/):
244+
This project uses GitHub Actions for CI/CD. The workflows can be found in [`.github/workflows/`](.github/workflows/).
159245

160246
- [`test.yml`](.github/workflows/test.yml) - Runs on pushes to the `main` branch and on all PRs
161247
- Tests across Python/Django version matrix

Justfile

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,32 @@ bootstrap:
2424
uv python install
2525
uv sync --locked
2626

27-
coverage:
28-
@just nox coverage
27+
coverage *ARGS:
28+
@just nox coverage {{ ARGS }}
2929

3030
lint:
3131
@just nox lint
3232

3333
lock *ARGS:
3434
uv lock {{ ARGS }}
3535

36+
manage *COMMAND:
37+
#!/usr/bin/env python
38+
import sys
39+
40+
try:
41+
from django.conf import settings
42+
from django.core.management import execute_from_command_line
43+
except ImportError as exc:
44+
raise ImportError(
45+
"Couldn't import Django. Are you sure it's installed and "
46+
"available on your PYTHONPATH environment variable? Did you "
47+
"forget to activate a virtual environment?"
48+
) from exc
49+
50+
settings.configure(INSTALLED_APPS=["django_github_app"])
51+
execute_from_command_line(sys.argv + "{{ COMMAND }}".split(" "))
52+
3653
test *ARGS:
3754
@just nox test {{ ARGS }}
3855

0 commit comments

Comments
 (0)