Skip to content

Commit 8630ea8

Browse files
feat: add github pipelines
1 parent e3a3fcb commit 8630ea8

File tree

8 files changed

+391
-1
lines changed

8 files changed

+391
-1
lines changed

.github/workflows/release.yml

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
name: Build and Release
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
permissions:
10+
contents: write
11+
issues: write
12+
pull-requests: write
13+
14+
jobs:
15+
# Determine if we should create a release
16+
semantic-release:
17+
name: Semantic Release
18+
runs-on: ubuntu-latest
19+
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
20+
outputs:
21+
new-release-published: ${{ steps.semantic.outputs.new-release-published }}
22+
new-release-version: ${{ steps.semantic.outputs.new-release-version }}
23+
new-release-git-tag: ${{ steps.semantic.outputs.new-release-git-tag }}
24+
steps:
25+
- name: Checkout
26+
uses: actions/checkout@v4
27+
with:
28+
fetch-depth: 0
29+
token: ${{ secrets.GITHUB_TOKEN }}
30+
31+
- name: Setup Node.js
32+
uses: actions/setup-node@v4
33+
with:
34+
node-version: '20'
35+
36+
- name: Install semantic-release
37+
run: |
38+
npm install -g semantic-release @semantic-release/changelog @semantic-release/git @semantic-release/github
39+
40+
- name: Run semantic-release
41+
id: semantic
42+
run: semantic-release
43+
env:
44+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
45+
46+
# Build binaries for all platforms
47+
build:
48+
name: Build ${{ matrix.os }}
49+
runs-on: ${{ matrix.os }}
50+
needs: semantic-release
51+
if: needs.semantic-release.outputs.new-release-published == 'true'
52+
strategy:
53+
fail-fast: false
54+
matrix:
55+
include:
56+
- os: windows-latest
57+
name: windows
58+
executable: glimpse.exe
59+
icon: app_icon.ico
60+
- os: ubuntu-latest
61+
name: linux
62+
executable: glimpse
63+
icon: app_icon.png
64+
- os: macos-latest
65+
name: macos
66+
executable: glimpse
67+
icon: app_icon.png
68+
69+
steps:
70+
- name: Checkout
71+
uses: actions/checkout@v4
72+
73+
- name: Set up Python
74+
uses: actions/setup-python@v4
75+
with:
76+
python-version: '3.13'
77+
78+
- name: Install uv (Windows)
79+
if: matrix.os == 'windows-latest'
80+
run: |
81+
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
82+
echo "$env:USERPROFILE\.cargo\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
83+
84+
- name: Install uv (Unix)
85+
if: matrix.os != 'windows-latest'
86+
run: |
87+
curl -LsSf https://astral.sh/uv/install.sh | sh
88+
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
89+
90+
- name: Install dependencies
91+
run: |
92+
uv pip install --system pyinstaller pyside6
93+
94+
- name: Create version file
95+
shell: bash
96+
run: |
97+
echo "VERSION = '${{ needs.semantic-release.outputs.new-release-version }}'" > src/version.py
98+
99+
- name: Build executable
100+
run: |
101+
pyinstaller glimpse.spec
102+
103+
- name: Create archive (Windows)
104+
if: matrix.os == 'windows-latest'
105+
run: |
106+
powershell -command "Compress-Archive -Path dist/glimpse.exe -DestinationPath glimpse-${{ needs.semantic-release.outputs.new-release-version }}-windows.zip"
107+
108+
- name: Create archive (Unix)
109+
if: matrix.os != 'windows-latest'
110+
run: |
111+
cd dist
112+
tar -czf ../glimpse-${{ needs.semantic-release.outputs.new-release-version }}-${{ matrix.name }}.tar.gz glimpse
113+
cd ..
114+
115+
- name: Upload artifacts
116+
uses: actions/upload-artifact@v4
117+
with:
118+
name: glimpse-${{ matrix.name }}
119+
path: |
120+
glimpse-*.zip
121+
glimpse-*.tar.gz
122+
123+
# Create GitHub release with all artifacts
124+
release:
125+
name: Create Release
126+
runs-on: ubuntu-latest
127+
needs: [semantic-release, build]
128+
if: needs.semantic-release.outputs.new-release-published == 'true'
129+
steps:
130+
- name: Checkout
131+
uses: actions/checkout@v4
132+
133+
- name: Download all artifacts
134+
uses: actions/download-artifact@v4
135+
with:
136+
path: ./artifacts
137+
138+
- name: Display structure of downloaded files
139+
run: ls -R ./artifacts
140+
141+
- name: Upload release assets
142+
uses: softprops/action-gh-release@v1
143+
with:
144+
tag_name: ${{ needs.semantic-release.outputs.new-release-git-tag }}
145+
name: Release ${{ needs.semantic-release.outputs.new-release-version }}
146+
files: |
147+
./artifacts/**/*.zip
148+
./artifacts/**/*.tar.gz
149+
generate_release_notes: true
150+
env:
151+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/test.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Test
2+
3+
on:
4+
pull_request:
5+
branches: [ main ]
6+
push:
7+
branches: [ main ]
8+
9+
jobs:
10+
test:
11+
name: Test on ${{ matrix.os }}
12+
runs-on: ${{ matrix.os }}
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
os: [ubuntu-latest, windows-latest, macos-latest]
17+
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v4
21+
22+
- name: Set up Python
23+
uses: actions/setup-python@v4
24+
with:
25+
python-version: '3.13'
26+
27+
- name: Install uv (Windows)
28+
if: matrix.os == 'windows-latest'
29+
run: |
30+
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
31+
echo "$env:USERPROFILE\.cargo\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
32+
33+
- name: Install uv (Unix)
34+
if: matrix.os != 'windows-latest'
35+
run: |
36+
curl -LsSf https://astral.sh/uv/install.sh | sh
37+
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
38+
39+
- name: Install dependencies
40+
run: |
41+
uv pip install --system pyside6
42+
43+
- name: Test import
44+
run: |
45+
python -c "
46+
import sys
47+
sys.path.insert(0, 'src')
48+
from ui.main_window import GlimpseViewer
49+
from version import get_version
50+
print(f'Glimpse v{get_version()} - Import successful')
51+
"
52+
53+
- name: Test version
54+
run: |
55+
python -c "
56+
import sys
57+
sys.path.insert(0, 'src')
58+
from version import get_version
59+
version = get_version()
60+
print(f'Version: {version}')
61+
assert version.count('.') >= 2, 'Version should be semantic (x.y.z)'
62+
"

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ build/
1212
dist/
1313
*.egg-info/
1414
*.spec
15+
!glimpse.spec
1516

1617
# Installer logs
1718
pip-log.txt

.releaserc.json

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
{
2+
"branches": ["main"],
3+
"plugins": [
4+
[
5+
"@semantic-release/commit-analyzer",
6+
{
7+
"preset": "conventionalcommits",
8+
"releaseRules": [
9+
{"type": "feat", "release": "minor"},
10+
{"type": "fix", "release": "patch"},
11+
{"type": "perf", "release": "patch"},
12+
{"type": "revert", "release": "patch"},
13+
{"type": "docs", "release": false},
14+
{"type": "style", "release": false},
15+
{"type": "chore", "release": false},
16+
{"type": "refactor", "release": "patch"},
17+
{"type": "test", "release": false},
18+
{"type": "build", "release": false},
19+
{"type": "ci", "release": false},
20+
{"breaking": true, "release": "major"}
21+
]
22+
}
23+
],
24+
[
25+
"@semantic-release/release-notes-generator",
26+
{
27+
"preset": "conventionalcommits",
28+
"presetConfig": {
29+
"types": [
30+
{"type": "feat", "section": "✨ Features", "hidden": false},
31+
{"type": "fix", "section": "🐛 Bug Fixes", "hidden": false},
32+
{"type": "perf", "section": "⚡ Performance Improvements", "hidden": false},
33+
{"type": "revert", "section": "⏪ Reverts", "hidden": false},
34+
{"type": "docs", "section": "📚 Documentation", "hidden": false},
35+
{"type": "style", "section": "💎 Styles", "hidden": false},
36+
{"type": "chore", "section": "🔧 Miscellaneous Chores", "hidden": true},
37+
{"type": "refactor", "section": "♻️ Code Refactoring", "hidden": false},
38+
{"type": "test", "section": "✅ Tests", "hidden": false},
39+
{"type": "build", "section": "🏗️ Build System", "hidden": false},
40+
{"type": "ci", "section": "🔄 Continuous Integration", "hidden": false}
41+
]
42+
}
43+
}
44+
],
45+
[
46+
"@semantic-release/changelog",
47+
{
48+
"changelogFile": "CHANGELOG.md"
49+
}
50+
],
51+
"@semantic-release/github",
52+
[
53+
"@semantic-release/git",
54+
{
55+
"assets": ["CHANGELOG.md", "src/version.py"],
56+
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
57+
}
58+
]
59+
]
60+
}

CONTRIBUTING.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Contributing to Glimpse
2+
3+
## Commit Message Format
4+
5+
This project uses [Conventional Commits](https://www.conventionalcommits.org/) for automatic semantic versioning and changelog generation.
6+
7+
### Format
8+
```
9+
<type>[optional scope]: <description>
10+
11+
[optional body]
12+
13+
[optional footer(s)]
14+
```
15+
16+
### Types
17+
- **feat**: A new feature (triggers minor version bump)
18+
- **fix**: A bug fix (triggers patch version bump)
19+
- **perf**: A performance improvement (triggers patch version bump)
20+
- **refactor**: Code refactoring (triggers patch version bump)
21+
- **docs**: Documentation changes (no version bump)
22+
- **style**: Code style changes (no version bump)
23+
- **test**: Adding or updating tests (no version bump)
24+
- **chore**: Maintenance tasks (no version bump)
25+
- **ci**: CI/CD changes (no version bump)
26+
- **build**: Build system changes (no version bump)
27+
28+
### Breaking Changes
29+
Add `BREAKING CHANGE:` in the footer or `!` after the type to trigger a major version bump.
30+
31+
### Examples
32+
```
33+
feat: add spacebar binding for play/pause timer
34+
fix: resolve icon loading issue on Linux
35+
feat!: redesign startup dialog (breaking change)
36+
docs: update installation instructions
37+
chore: update dependencies
38+
```
39+
40+
## Release Process
41+
42+
Releases are automated using GitHub Actions:
43+
44+
1. **Push to main**: Commits are analyzed for semantic versioning
45+
2. **Version bump**: Automatic version increment based on commit types
46+
3. **Changelog**: Auto-generated from commit messages
47+
4. **Cross-platform builds**: Windows, Linux, and macOS binaries created
48+
5. **GitHub release**: Automatic release with downloadable assets
49+
50+
## Development Workflow
51+
52+
1. Create feature branch: `git checkout -b feat/my-feature`
53+
2. Make changes with conventional commits
54+
3. Push branch: `git push origin feat/my-feature`
55+
4. Create Pull Request
56+
5. CI tests run automatically
57+
6. After merge to main, release is automatically created if needed
58+
59+
## Building Locally
60+
61+
```bash
62+
# Install dependencies
63+
uv pip install pyside6 pyinstaller
64+
65+
# Build executable
66+
pyinstaller glimpse.spec
67+
68+
# Output in dist/ folder
69+
```

glimpse.spec

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# -*- mode: python ; coding: utf-8 -*-
2+
3+
4+
a = Analysis(
5+
['main.py'],
6+
pathex=[],
7+
binaries=[],
8+
datas=[('app_icon.png', '.'), ('app_icon.ico', '.')],
9+
hiddenimports=[],
10+
hookspath=[],
11+
hooksconfig={},
12+
runtime_hooks=[],
13+
excludes=[],
14+
noarchive=False,
15+
optimize=0,
16+
)
17+
pyz = PYZ(a.pure)
18+
19+
exe = EXE(
20+
pyz,
21+
a.scripts,
22+
a.binaries,
23+
a.datas,
24+
[],
25+
name='glimpse',
26+
debug=False,
27+
bootloader_ignore_signals=False,
28+
strip=False,
29+
upx=True,
30+
upx_exclude=[],
31+
runtime_tmpdir=None,
32+
console=False,
33+
disable_windowed_traceback=False,
34+
argv_emulation=False,
35+
target_arch=None,
36+
codesign_identity=None,
37+
entitlements_file=None,
38+
icon='app_icon.png',
39+
)

0 commit comments

Comments
 (0)