Skip to content

Commit ab45593

Browse files
authored
Refactor configuration and enhance setup with UV support (#215)
2 parents fbfc2b5 + b64cc82 commit ab45593

File tree

19 files changed

+823
-628
lines changed

19 files changed

+823
-628
lines changed

.github/workflows/main.yml

Lines changed: 105 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -1,167 +1,110 @@
11
name: Create Release from CHANGELOG
22

33
on:
4-
push:
5-
branches: [main]
6-
paths:
7-
- "CHANGELOG.md" # Only trigger when CHANGELOG.md is updated
4+
push:
5+
branches: [main]
6+
paths:
7+
- "CHANGELOG.md" # Only trigger when CHANGELOG.md is updated
88

99
jobs:
10-
release:
11-
runs-on: ubuntu-latest
12-
permissions:
13-
contents: write
14-
15-
steps:
16-
- name: Checkout code
17-
uses: actions/checkout@v4
18-
with:
19-
fetch-depth: 0 # Fetch all history to get commit messages
20-
21-
- name: Extract latest version and notes
22-
id: changelog
23-
run: |
24-
# Extract the first version number from CHANGELOG.md
25-
VERSION=$(grep -m 1 '^## v' CHANGELOG.md | sed 's/^## \(v[0-9.]*[0-9]\(-[a-zA-Z0-9]*\)*\).*/\1/')
26-
echo "version=$VERSION" >> $GITHUB_OUTPUT
27-
28-
# Extract notes for this version (everything between this version header and the next version header)
29-
NOTES=$(awk -v ver="$VERSION" '
30-
BEGIN { found=0; capture=0; notes=""; }
31-
$0 ~ "^## " ver { found=1; capture=1; next; }
32-
$0 ~ /^## v/ && capture==1 { capture=0; }
33-
capture==1 { notes = notes $0 "\n"; }
34-
END { print notes; }
35-
' CHANGELOG.md)
36-
37-
# Get recent commits since last tag with GitHub usernames
38-
PREVIOUS_TAG=$(git describe --tags --abbrev=0 --match "v*" 2>/dev/null || echo "")
39-
40-
# Function to get GitHub username from email
41-
get_github_username() {
42-
local email="$1"
43-
local commit_hash="$2"
44-
45-
# First try to extract username from GitHub noreply email
46-
if [[ "$email" =~ ([0-9]+\+)?([^@]+)@users\.noreply\.github\.com ]]; then
47-
echo "${BASH_REMATCH[2]}"
48-
return
49-
fi
50-
51-
# Try to get GitHub username via API using commit hash
52-
local github_user=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
53-
"https://api.github.com/repos/$GITHUB_REPOSITORY/commits/$commit_hash" | \
54-
jq -r '.author.login // empty' 2>/dev/null)
55-
56-
if [ -n "$github_user" ] && [ "$github_user" != "null" ]; then
57-
echo "$github_user"
58-
return
59-
fi
60-
61-
# Fallback: try to get user by email via API
62-
local api_user=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
63-
"https://api.github.com/search/users?q=$email+in:email" | \
64-
jq -r '.items[0].login // empty' 2>/dev/null)
65-
66-
if [ -n "$api_user" ] && [ "$api_user" != "null" ]; then
67-
echo "$api_user"
68-
else
69-
# Final fallback: use the part before @ in email
70-
echo "${email%%@*}"
71-
fi
72-
}
73-
74-
# Get ALL conventional commits, excluding merge commits to avoid duplicates
75-
if [ -z "$PREVIOUS_TAG" ]; then
76-
COMMIT_DATA=$(git log --pretty=format:"%H|%ae|%s" --no-merges --grep="^\(feat\|fix\|docs\|style\|refactor\|perf\|test\|build\|ci\|chore\|revert\)")
77-
else
78-
COMMIT_DATA=$(git log ${PREVIOUS_TAG}..HEAD --pretty=format:"%H|%ae|%s" --no-merges --grep="^\(feat\|fix\|docs\|style\|refactor\|perf\|test\|build\|ci\|chore\|revert\)")
79-
fi
80-
81-
# Initialize categorized commit arrays
82-
FEATURES=""
83-
BUGFIXES=""
84-
OTHER_COMMITS=""
85-
86-
# Process ALL matching commits and categorize them
87-
while IFS='|' read -r hash email subject; do
88-
[ -z "$hash" ] && continue
89-
90-
# Get full commit message for PR detection
91-
message=$(git show -s --format=%B $hash)
92-
93-
# Extract username
94-
username=$(get_github_username "$email" "$hash")
95-
96-
# Check for ANY PR reference (#number)
97-
if [[ "$message" =~ \#([0-9]+) ]]; then
98-
pr_num=" (#${BASH_REMATCH[1]})"
99-
else
100-
pr_num=""
101-
fi
102-
103-
# Categorize based on conventional commit type
104-
if [[ "$subject" =~ ^feat(\(.+\))?:* ]]; then
105-
FEATURES="${FEATURES} - ${subject}${pr_num} (@$username)\n"
106-
elif [[ "$subject" =~ ^fix(\(.+\))?:* ]]; then
107-
BUGFIXES="${BUGFIXES} - ${subject}${pr_num} (@$username)\n"
108-
else
109-
OTHER_COMMITS="${OTHER_COMMITS} - ${subject}${pr_num} (@$username)\n"
110-
fi
111-
done <<< "$COMMIT_DATA"
112-
113-
# Build categorized commits section
114-
COMMITS=""
115-
if [ -n "$FEATURES" ]; then
116-
COMMITS="${COMMITS}#### 🚀 Features\n${FEATURES}\n"
117-
fi
118-
if [ -n "$BUGFIXES" ]; then
119-
COMMITS="${COMMITS}#### 🐛 Bug Fixes\n${BUGFIXES}\n"
120-
fi
121-
if [ -n "$OTHER_COMMITS" ]; then
122-
COMMITS="${COMMITS}#### 📝 Other Commits\n${OTHER_COMMITS}\n"
123-
fi
124-
125-
# Combine CHANGELOG notes with categorized commit messages
126-
if [ -n "$COMMITS" ]; then
127-
FULL_NOTES="${NOTES}\n\n### Commits\n${COMMITS}"
128-
else
129-
FULL_NOTES="${NOTES}"
130-
fi
131-
132-
# Save notes to output with correct GitHub multiline syntax
133-
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
134-
echo "notes<<$EOF" >> $GITHUB_OUTPUT
135-
echo -e "$FULL_NOTES" >> $GITHUB_OUTPUT
136-
echo "$EOF" >> $GITHUB_OUTPUT
137-
138-
# For debugging
139-
echo "Found version: $VERSION"
140-
echo "Release notes excerpt: $(echo "$NOTES" | head -3)..."
141-
echo "Commit messages excerpt: $(echo "$COMMITS" | head -3)..."
142-
143-
- name: Check for existing release
144-
id: check_release
145-
run: |
146-
VERSION=${{ steps.changelog.outputs.version }}
147-
if gh release view $VERSION &>/dev/null; then
148-
echo "Release already exists: $VERSION"
149-
echo "exists=true" >> $GITHUB_OUTPUT
150-
else
151-
echo "No existing release found for: $VERSION"
152-
echo "exists=false" >> $GITHUB_OUTPUT
153-
fi
154-
env:
155-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
156-
157-
- name: Create GitHub Release
158-
if: steps.check_release.outputs.exists == 'false'
159-
uses: softprops/action-gh-release@v1
160-
with:
161-
tag_name: ${{ steps.changelog.outputs.version }}
162-
name: "Release ${{ steps.changelog.outputs.version }}"
163-
body: ${{ steps.changelog.outputs.notes }}
164-
draft: false
165-
prerelease: ${{ contains(steps.changelog.outputs.version, '-') }}
166-
env:
167-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
10+
release:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: write
14+
15+
steps:
16+
- name: Checkout code
17+
uses: actions/checkout@v4
18+
19+
- name: Extract latest version and notes
20+
id: changelog
21+
run: |
22+
# Extract the first version header from CHANGELOG.md
23+
# Supports both formats: ## [version] and ## version
24+
FIRST_HEADER=$(grep -m 1 '^## \[.*\]$\|^## v' CHANGELOG.md)
25+
26+
# Extract version from header
27+
if [[ "$FIRST_HEADER" =~ ^\#\#\ \[(.*)\] ]]; then
28+
# Format: ## [version]
29+
VERSION="${BASH_REMATCH[1]}"
30+
elif [[ "$FIRST_HEADER" =~ ^\#\#\ (v[0-9].*) ]]; then
31+
# Format: ## vX.Y.Z
32+
VERSION="${BASH_REMATCH[1]}"
33+
else
34+
echo "No valid version header found in CHANGELOG.md"
35+
exit 1
36+
fi
37+
38+
echo "version=$VERSION" >> $GITHUB_OUTPUT
39+
echo "Found version: $VERSION"
40+
41+
# Check if version is "Unreleased"
42+
if [[ "$VERSION" =~ ^[Uu]nreleased$ ]]; then
43+
echo "is_unreleased=true" >> $GITHUB_OUTPUT
44+
echo "Version is Unreleased, skipping release creation"
45+
exit 0
46+
else
47+
echo "is_unreleased=false" >> $GITHUB_OUTPUT
48+
fi
49+
50+
# Extract notes for this version (everything between this version header and the next ## header)
51+
NOTES=$(awk -v ver="$VERSION" '
52+
BEGIN { found=0; capture=0; notes=""; }
53+
/^## \[/ {
54+
if (!found && index($0, ver) > 0) {
55+
found=1;
56+
capture=1;
57+
next;
58+
} else if (capture==1) {
59+
capture=0;
60+
}
61+
}
62+
/^## v/ {
63+
if (!found && index($0, ver) > 0) {
64+
found=1;
65+
capture=1;
66+
next;
67+
} else if (capture==1) {
68+
capture=0;
69+
}
70+
}
71+
capture==1 { notes = notes $0 "\n"; }
72+
END { print notes; }
73+
' CHANGELOG.md)
74+
75+
# Save notes to output with correct GitHub multiline syntax
76+
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
77+
echo "notes<<$EOF" >> $GITHUB_OUTPUT
78+
echo "$NOTES" >> $GITHUB_OUTPUT
79+
echo "$EOF" >> $GITHUB_OUTPUT
80+
81+
# For debugging
82+
echo "Release notes excerpt:"
83+
echo "$NOTES" | head -10
84+
85+
- name: Check for existing release
86+
if: steps.changelog.outputs.is_unreleased != 'true'
87+
id: check_release
88+
run: |
89+
VERSION=${{ steps.changelog.outputs.version }}
90+
if gh release view $VERSION &>/dev/null; then
91+
echo "Release already exists: $VERSION"
92+
echo "exists=true" >> $GITHUB_OUTPUT
93+
else
94+
echo "No existing release found for: $VERSION"
95+
echo "exists=false" >> $GITHUB_OUTPUT
96+
fi
97+
env:
98+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
99+
100+
- name: Create GitHub Release
101+
if: steps.changelog.outputs.is_unreleased != 'true' && steps.check_release.outputs.exists == 'false'
102+
uses: softprops/action-gh-release@v1
103+
with:
104+
tag_name: ${{ steps.changelog.outputs.version }}
105+
name: "Release ${{ steps.changelog.outputs.version }}"
106+
body: ${{ steps.changelog.outputs.notes }}
107+
draft: false
108+
prerelease: ${{ contains(steps.changelog.outputs.version, '-') }}
109+
env:
110+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

CHANGELOG.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,30 @@
22

33
All notable changes to this project will be documented in this file.
44

5-
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [1.10.1-alpha]
9+
10+
### Added
11+
12+
- **UV Support**: Added support for UV (Astral's fast Python package manager) with automatic detection and seamless fallback to pip.
13+
UV is used to install the venv, which is faster and more efficient than pip.
14+
15+
### Changed
16+
17+
- Enhanced setup.sh with UV detection and conditional usage
18+
- Improved upgrade logging to indicate whether UV or pip is being used
19+
20+
### Fixed
21+
22+
- Fixed a bug where the venv installation process could fail due to wrong directory usage on upgrade module.
23+
Now, the package upgrade process is uses setup.sh instead of upgrade module for better simplified installation process.
24+
25+
### Removed
26+
27+
- Locale and batch_mode on configuration which they was violate YAGNI. May be added back in the future if needed
28+
- Commit history writing to release notes
629

730
## v1.10.0-alpha
831

README.md

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,48 @@ Turkish: [README.tr.md](README.tr.md)
1414
> - Detailed information: [wiki.md](docs/wiki.md)
1515
1616
- **Supported Applications:**
17-
- Super-Productivity, Siyuan, Joplin, Standard-notes, Logseq, QOwnNotes, Tagspaces, Zen-Browser, Zettlr, HeroicGamesLauncher, KDiskMark, AppFlowy, Obsidian, FreeTube
18-
- Applications without verification (developer doesn't provide hash):
19-
- WeekToDo
20-
- More can be found in the [catalog](my_unicorn/catalog/) folder.
17+
- Super-Productivity, Siyuan, Joplin, Standard-notes, Logseq, QOwnNotes, Tagspaces, Zen-Browser, Zettlr, HeroicGamesLauncher, KDiskMark, AppFlowy, Obsidian, FreeTube
18+
- Applications without verification (developer doesn't provide hash):
19+
- WeekToDo
20+
- More can be found in the [catalog](my_unicorn/catalog/) folder.
2121
- **Supported hash types:**
22-
- sha256, sha512
22+
- sha256, sha512
2323

2424
# 💡 Installation
2525

2626
> [!TIP]
2727
> Installer script uses venv to install the needed dependencies.
2828
29-
1. Open a terminal and clone this repo (make sure you have git installed):
29+
1. Open a terminal and clone this repo (make sure you have git installed):
3030

3131
```bash
3232
cd ~/Downloads &
3333
git clone https://github.com/Cyber-Syntax/my-unicorn.git
3434
```
3535

36-
2. Build as a package:
36+
2. Install `uv` (RECOMMENDED):
37+
38+
> `uv` would be used to install the dependencies to venv, it is more efficient than pip.
39+
40+
```bash
41+
# fedora
42+
sudo dnf install uv
43+
# arch
44+
sudo pacman -S uv
45+
# or `uv` astral official standalone installer
46+
curl -LsSf https://astral.sh/uv/install.sh | sh
47+
```
48+
49+
3. Build as a package:
3750

3851
```bash
52+
# Go to the project directory
3953
cd my-unicorn &
40-
sh setup.sh install
54+
# Run installer (automatically uses UV if available)
55+
./setup.sh install
4156
```
4257

43-
3. Start using my-unicorn:
58+
4. Start using my-unicorn:
4459

4560
```bash
4661
my-unicorn --help # to see the command options
@@ -53,14 +68,14 @@ Turkish: [README.tr.md](README.tr.md)
5368
5469
- **GitHub URL:** The repository URL of the app (e.g., `https://github.com/johannesjo/super-productivity`).
5570
- Hash type and Hash file name are automatically detected. You need to provide below informations, if the app compatibility is not available or error occurs:
56-
- **Hash type:** Specify the hash type (e.g., sha512 for super-productivity).
57-
- **Hash verification issues:** If the hash verification fails, you can manually add the hash to the JSON file:
58-
- Look for the latest hash in the GitHub release page (e.g., [super-productivity releases](https://github.com/johannesjo/super-productivity/releases)).
59-
- Check the [catalog](my_unicorn/catalog/) folder for examples.
71+
- **Hash type:** Specify the hash type (e.g., sha512 for super-productivity).
72+
- **Hash verification issues:** If the hash verification fails, you can manually add the hash to the JSON file:
73+
- Look for the latest hash in the GitHub release page (e.g., [super-productivity releases](https://github.com/johannesjo/super-productivity/releases)).
74+
- Check the [catalog](my_unicorn/catalog/) folder for examples.
6075
6176
# **🙏 Support This Project**
6277
6378
- **Consider giving it a star ⭐** on GitHub to show your support and keep me motivated on my coding journey!
6479
- **Testing:** It would be great if you could test the script and provide feedback on any issues you encounter.
6580
- **💖 Sponsor me:** If you'd like to support my work and help me continue learning and building projects, consider sponsoring me:
66-
- [![Sponsor Me](https://img.shields.io/badge/Sponsor-💖-brightgreen)](https://github.com/sponsors/Cyber-Syntax)
81+
- [![Sponsor Me](https://img.shields.io/badge/Sponsor-💖-brightgreen)](https://github.com/sponsors/Cyber-Syntax)

docs/architecture/configuration.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ Default values and where they are defined
4141
config_version = 1.0.0
4242
max_concurrent_downloads = 5
4343
max_backup = 1
44-
batch_mode = true
45-
locale = en_US
4644
log_level = INFO
4745
console_log_level = WARNING
4846
[network]

0 commit comments

Comments
 (0)