Skip to content

Commit 9a33d01

Browse files
And just like that, briefcase-pythonanywhere.
0 parents  commit 9a33d01

File tree

14 files changed

+1915
-0
lines changed

14 files changed

+1915
-0
lines changed

.github/workflows/release.yml

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*.*.*'
7+
workflow_dispatch:
8+
9+
jobs:
10+
test:
11+
uses: ./.github/workflows/test.yml
12+
13+
build_package:
14+
runs-on: ubuntu-latest
15+
needs: test
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
19+
20+
- name: Install uv
21+
uses: astral-sh/setup-uv@6b9c6063abd6010835644d4c2e1bef4cf5cd0fca # v6.0.1
22+
23+
- name: Set up Python
24+
run: uv python install 3.13
25+
26+
- name: Check tag matches version files
27+
run: |
28+
TAG_VERSION="${GITHUB_REF##*/}"
29+
TAG_VERSION_NO_PREFIX="${TAG_VERSION#v}"
30+
echo "Tag version: $TAG_VERSION (stripped: $TAG_VERSION_NO_PREFIX)"
31+
32+
PYPROJECT_VERSION=$(grep '^version =' pyproject.toml | sed 's/version = "\(.*\)"/\1/')
33+
echo "pyproject.toml version: $PYPROJECT_VERSION"
34+
35+
INIT_VERSION=$(grep '^__version__ =' src/briefcase_pythonanywhere/__init__.py | sed 's/__version__ = "\(.*\)"/\1/')
36+
echo "__init__.py version: $INIT_VERSION"
37+
38+
if [ "$TAG_VERSION_NO_PREFIX" != "$PYPROJECT_VERSION" ]; then
39+
echo "Tag version ($TAG_VERSION_NO_PREFIX) does not match pyproject.toml version ($PYPROJECT_VERSION)" >&2
40+
exit 1
41+
fi
42+
43+
if [ "$TAG_VERSION_NO_PREFIX" != "$INIT_VERSION" ]; then
44+
echo "Tag version ($TAG_VERSION_NO_PREFIX) does not match __init__.py version ($INIT_VERSION)" >&2
45+
exit 1
46+
fi
47+
48+
if [ "$PYPROJECT_VERSION" != "$INIT_VERSION" ]; then
49+
echo "pyproject.toml version ($PYPROJECT_VERSION) does not match __init__.py version ($INIT_VERSION)" >&2
50+
exit 1
51+
fi
52+
shell: bash
53+
54+
- name: Build package
55+
run: uv build
56+
57+
- name: Publish to PyPI
58+
uses: pypa/gh-action-pypi-publish@release/v1
59+
with:
60+
user: __token__
61+
password: ${{ secrets.PYPI_API_TOKEN }}
62+
63+
- name: Upload build artifacts
64+
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
65+
with:
66+
name: dist
67+
path: dist/
68+
69+
create_release:
70+
runs-on: ubuntu-latest
71+
needs: build_package
72+
steps:
73+
- name: Download build artifacts
74+
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
75+
with:
76+
name: dist
77+
path: dist/
78+
79+
- name: Create Release
80+
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
81+
with:
82+
files: |
83+
dist/*
84+
env:
85+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
86+
87+
deploy_docs:
88+
runs-on: ubuntu-latest
89+
needs: build_package
90+
steps:
91+
- name: Checkout code
92+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
93+
94+
- name: Install uv
95+
uses: astral-sh/setup-uv@6b9c6063abd6010835644d4c2e1bef4cf5cd0fca # v6.0.1
96+
97+
- name: Set up Python
98+
run: uv python install 3.13
99+
100+
- name: Build documentation
101+
run: uvx mkdocs build
102+
103+
- name: Setup SSH key
104+
uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1
105+
with:
106+
ssh-private-key: ${{ secrets.DOCS_DEPLOY_SSH_KEY }}
107+
108+
- name: Add server to known hosts
109+
run: |
110+
ssh-keyscan -H ssh.pythonanywhere.com >> ~/.ssh/known_hosts
111+
112+
- name: Deploy to PythonAnywhere
113+
run: |
114+
rsync -av --delete site/ briefcase@ssh.pythonanywhere.com:/home/briefcase/docs/

.github/workflows/test.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
branches:
6+
- '**'
7+
tags-ignore:
8+
- 'v*'
9+
pull_request:
10+
workflow_call:
11+
12+
jobs:
13+
test:
14+
runs-on: ubuntu-latest
15+
strategy:
16+
matrix:
17+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
18+
19+
name: Python ${{ matrix.python-version }}
20+
steps:
21+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
22+
23+
- name: Install uv
24+
uses: astral-sh/setup-uv@6b9c6063abd6010835644d4c2e1bef4cf5cd0fca # v6.0.1
25+
26+
- name: Set up Python
27+
run: uv python install ${{ matrix.python-version }}
28+
29+
- name: Install dependencies
30+
run: uv sync
31+
32+
- name: Test with coverage
33+
run: uv run pytest --cov --cov-fail-under=100
34+
35+
pre-commit:
36+
runs-on: ubuntu-latest
37+
steps:
38+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
39+
40+
- name: Install uv
41+
uses: astral-sh/setup-uv@6b9c6063abd6010835644d4c2e1bef4cf5cd0fca # v6.0.1
42+
43+
- name: Set up Python
44+
run: uv python install 3.13
45+
46+
- name: Install dependencies
47+
run: uv sync
48+
49+
- name: Run pre-commit
50+
uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1

.gitignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*.egg-info/
5+
dist/
6+
7+
# Virtual environments
8+
.venv/
9+
10+
# Coverage
11+
.coverage
12+
htmlcov/
13+
14+
# MkDocs
15+
site/

.pre-commit-config.yaml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
repos:
2+
- repo: https://github.com/pre-commit/pre-commit-hooks
3+
rev: v6.0.0
4+
hooks:
5+
- id: check-toml
6+
- id: check-yaml
7+
- id: check-case-conflict
8+
- id: check-docstring-first
9+
- id: end-of-file-fixer
10+
- id: trailing-whitespace
11+
- repo: https://github.com/PyCQA/docformatter
12+
rev: v1.7.7
13+
hooks:
14+
- id: docformatter
15+
args: [--in-place, --black]
16+
- repo: https://github.com/astral-sh/ruff-pre-commit
17+
rev: v0.15.2
18+
hooks:
19+
- id: ruff-format
20+
- id: ruff-check
21+
args: [ --fix ]
22+
- repo: local
23+
hooks:
24+
- id: ty-check
25+
name: ty
26+
entry: uvx ty check
27+
language: system
28+
types: [python]
29+
pass_filenames: false
30+
- repo: https://github.com/codespell-project/codespell
31+
rev: v2.4.1
32+
hooks:
33+
- id: codespell
34+
additional_dependencies: ['.[toml]']

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 PythonAnywhere
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# briefcase-pythonanywhere
2+
3+
A [Briefcase](https://briefcase.readthedocs.io/) publication channel plugin for deploying static web apps to [PythonAnywhere](https://www.pythonanywhere.com/).
4+
5+
## Prerequisites
6+
7+
* A PythonAnywhere account
8+
* An API token (from your [Account page](https://www.pythonanywhere.com/account/#api_token))
9+
10+
## Installation
11+
12+
```console
13+
$ pip install briefcase-pythonanywhere
14+
```
15+
16+
## Quick start
17+
18+
Build and package your web app:
19+
20+
```console
21+
$ briefcase create web static
22+
$ briefcase build web static
23+
$ briefcase package web static
24+
```
25+
26+
Set your PythonAnywhere API token:
27+
28+
```console
29+
$ export API_TOKEN=your-api-token-here
30+
```
31+
32+
Publish:
33+
34+
```console
35+
$ briefcase publish web static
36+
```
37+
38+
Your app will be deployed to `https://<username>.pythonanywhere.com/`.
39+
40+
## Documentation
41+
42+
Full documentation is available at [https://briefcase.pythonanywhere.com/](https://briefcase.pythonanywhere.com/).
43+
44+
## Contributing
45+
46+
Development requires [uv](https://docs.astral.sh/uv/getting-started/installation/).
47+
48+
```console
49+
$ git clone https://github.com/pythonanywhere/briefcase-pythonanywhere.git
50+
$ cd briefcase-pythonanywhere
51+
$ uv sync
52+
$ uvx pre-commit install
53+
$ uv run pytest
54+
```
55+
56+
## License
57+
58+
MIT license.

0 commit comments

Comments
 (0)