-
-
Notifications
You must be signed in to change notification settings - Fork 631
Add CHANGELOG.md management and update CI release workflow #1331
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,144 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: Release Prep | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| workflow_dispatch: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| inputs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| version: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: "Version to release (X.Y.Z format — no v prefix)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contents: write | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pull-requests: write | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| release-prep: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Checkout code | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Verify all mutable action refs in workflows
rg -nP 'uses:\s*[^@]+@v\d+(\.\d+)?(\.\d+)?\b' .github/workflowsRepository: AOSSIE-Org/PictoPy Length of output: 4338 🏁 Script executed: cat -n .github/workflows/release-prep.yml | sed -n '15,30p'Repository: AOSSIE-Org/PictoPy Length of output: 548 Pin GitHub Actions to immutable commit SHAs Lines 20 and 25 use mutable tags ( Affected linesReplace with pinned commit SHAs, for example: 🧰 Tools🪛 zizmor (1.25.2)[error] 20-20: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy) (unpinned-uses) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fetch-depth: 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Setup Node.js | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/setup-node@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| node-version: lts/* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Bump version across manifests | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: npm run version:bump -- ${{ inputs.version }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+30
to
+31
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Validate Line 30 (and downstream lines in git/gh commands) expands user-provided workflow input directly inside Suggested fix+ - name: Validate release version
+ env:
+ RAW_VERSION: ${{ inputs.version }}
+ run: |
+ if [[ ! "$RAW_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
+ echo "Error: version must be X.Y.Z (no v prefix)"
+ exit 1
+ fi
+ echo "VERSION=$RAW_VERSION" >> "$GITHUB_ENV"
+
- name: Bump version across manifests
- run: npm run version:bump -- ${{ inputs.version }}
+ run: npm run version:bump -- "$VERSION"
...
- name: Commit and push prep branch
run: |
...
- git checkout -b release/prep-${{ inputs.version }}
+ git checkout -b "release/prep-$VERSION"
...
- git commit -m "chore: prepare release ${{ inputs.version }}"
- git push origin release/prep-${{ inputs.version }}
+ git commit -m "chore: prepare release $VERSION"
+ git push origin "release/prep-$VERSION"
...
- name: Open pull request
...
run: |
gh pr create \
- --title "chore: release ${{ inputs.version }}" \
- --body "## Release Prep: \`${{ inputs.version }}\`
+ --title "chore: release $VERSION" \
+ --body "## Release Prep: \`$VERSION\`
...
- - Version bumped to \`${{ inputs.version }}\` across all manifest files
- - CHANGELOG.md updated with a draft \`[${{ inputs.version }}]\` entry
+ - Version bumped to \`$VERSION\` across all manifest files
+ - CHANGELOG.md updated with a draft \`[$VERSION]\` entry
...
- After merging, create the GitHub Release with tag \`v${{ inputs.version }}\` to trigger the build pipeline." \
+ After merging, create the GitHub Release with tag \`v$VERSION\` to trigger the build pipeline." \
--base main \
- --head release/prep-${{ inputs.version }} \
+ --head "release/prep-$VERSION" \
--assignee ${{ github.actor }}Also applies to: 117-120, 126-141 🧰 Tools🪛 zizmor (1.25.2)[error] 30-30: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Generate CHANGELOG section | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| VERSION: ${{ inputs.version }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DATE=$(date -u +%Y-%m-%d) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Find last stable release tag (ignore test/pre-release tags) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| LAST_TAG=$(git tag -l --sort=-version:refname | grep -E '^v?[0-9]+\.[0-9]+\.[0-9]+$' | head -1) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Last stable tag: ${LAST_TAG:-none}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Fetch PRs merged since last stable tag | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -n "$LAST_TAG" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SINCE_DATE=$(git log -1 --format=%aI "${LAST_TAG}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PRS_JSON=$(gh pr list --state merged --search "merged:>${SINCE_DATE}" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --json number,title,labels,author --limit 200) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PRS_JSON=$(gh pr list --state merged \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --json number,title,labels,author --limit 200) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Group PRs by Release Drafter label categories | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ADDED=$(echo "$PRS_JSON" | jq -r ' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .[] | select(.labels | map(.name) | any(. == "enhancement" or . == "UI")) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | "- \(.title) (#\(.number)) by @\(.author.login)"') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| FIXED=$(echo "$PRS_JSON" | jq -r ' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .[] | select(.labels | map(.name) | any(. == "bug")) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | "- \(.title) (#\(.number)) by @\(.author.login)"') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CHANGED=$(echo "$PRS_JSON" | jq -r ' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .[] | select(.labels | map(.name) | any(. == "documentation")) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | "- \(.title) (#\(.number)) by @\(.author.login)"') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| OTHER=$(echo "$PRS_JSON" | jq -r ' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .[] | select( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (.labels | map(.name) | any(. == "enhancement" or . == "UI" or . == "bug" or . == "documentation")) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | not) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | "- \(.title) (#\(.number)) by @\(.author.login)"') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Build section | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SECTION="## [$VERSION] - $DATE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <!-- Auto-generated draft. Review and edit before merging. -->" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [ -n "$ADDED" ] && SECTION="$SECTION | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Added | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $ADDED" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [ -n "$FIXED" ] && SECTION="$SECTION | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Fixed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $FIXED" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [ -n "$CHANGED" ] && SECTION="$SECTION | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Changed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $CHANGED" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [ -n "$OTHER" ] && SECTION="$SECTION | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Other | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $OTHER" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "$SECTION" > /tmp/section.md | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Insert section after ## [Unreleased] in CHANGELOG.md | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| python3 << 'PYEOF' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with open('CHANGELOG.md', 'r') as f: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content = f.read() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with open('/tmp/section.md', 'r') as f: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| section = f.read().strip() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| marker = '## [Unreleased]' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| idx = content.find(marker) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if idx == -1: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| raise SystemExit('Error: [Unreleased] header not found in CHANGELOG.md') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| insert_pos = idx + len(marker) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| new_content = content[:insert_pos] + '\n\n' + section + '\n' + content[insert_pos:] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with open('CHANGELOG.md', 'w') as f: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f.write(new_content) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+97
to
+109
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guard against duplicate The insertion logic always appends after Suggested fix - name: Generate CHANGELOG section
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ inputs.version }}
run: |
...
# Insert section after ## [Unreleased] in CHANGELOG.md
python3 << 'PYEOF'
+ import os
with open('CHANGELOG.md', 'r') as f:
content = f.read()
with open('/tmp/section.md', 'r') as f:
section = f.read().strip()
+ version = os.environ['VERSION']
+ header = f'## [{version}]'
+ if header in content:
+ raise SystemExit(f'Error: {header} already exists in CHANGELOG.md')
marker = '## [Unreleased]'
idx = content.find(marker)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print('CHANGELOG.md updated.') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PYEOF | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Commit and push prep branch | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| git config user.name "github-actions[bot]" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| git config user.email "github-actions[bot]@users.noreply.github.com" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| git checkout -b release/prep-${{ inputs.version }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| git add package.json frontend/package.json frontend/src-tauri/Cargo.toml CHANGELOG.md | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| git commit -m "chore: prepare release ${{ inputs.version }}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| git push origin release/prep-${{ inputs.version }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Open pull request | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| gh pr create \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --title "chore: release ${{ inputs.version }}" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --body "## Release Prep: \`${{ inputs.version }}\` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Auto-generated by the release prep workflow. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### What's included | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Version bumped to \`${{ inputs.version }}\` across all manifest files | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - CHANGELOG.md updated with a draft \`[${{ inputs.version }}]\` entry | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Before merging | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - [ ] Review and clean up the CHANGELOG entry | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - [ ] Verify version strings in \`package.json\`, \`frontend/package.json\`, and \`frontend/src-tauri/Cargo.toml\` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - [ ] Run \`cargo check\` in \`frontend/src-tauri/\` to regenerate \`Cargo.lock\` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| After merging, create the GitHub Release with tag \`v${{ inputs.version }}\` to trigger the build pipeline." \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --base main \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --head release/prep-${{ inputs.version }} \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --assignee ${{ github.actor }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| # Changelog | ||
|
|
||
| All notable changes to PictoPy will be documented in this file. | ||
|
|
||
| The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), | ||
| and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
|
|
||
| ## [Unreleased] | ||
|
|
||
| ## [1.1.0] - 2026-05-22 | ||
|
|
||
| ### Added | ||
|
|
||
| - Settings page with folder and user preference management ([#606](https://github.com/AOSSIE-Org/PictoPy/pull/606), [#516](https://github.com/AOSSIE-Org/PictoPy/pull/516)) | ||
| - Memories backend implementation ([#777](https://github.com/AOSSIE-Org/PictoPy/pull/777)) | ||
| - Global face reclustering option with backend API and UI support ([#560](https://github.com/AOSSIE-Org/PictoPy/pull/560)) | ||
| - Centralized logging system ([#548](https://github.com/AOSSIE-Org/PictoPy/pull/548)) | ||
| - Live progress tracking with polling and animated progress bar ([#574](https://github.com/AOSSIE-Org/PictoPy/pull/574)) | ||
| - Scrollbar timeline with month-year markers for Home and AI Tagging pages ([#552](https://github.com/AOSSIE-Org/PictoPy/pull/552)) | ||
| - Empty state placeholders for AI tagging and home pages ([#549](https://github.com/AOSSIE-Org/PictoPy/pull/549)) | ||
| - Camera selection for the webcam component ([#624](https://github.com/AOSSIE-Org/PictoPy/pull/624)) | ||
| - Advanced zoom-on-scroll and panning logic in image preview ([#530](https://github.com/AOSSIE-Org/PictoPy/pull/530), [#835](https://github.com/AOSSIE-Org/PictoPy/pull/835)) | ||
| - Slideshow looping for seamless playback ([#1100](https://github.com/AOSSIE-Org/PictoPy/pull/1100)) | ||
| - Smooth exit animation for the image details panel ([#978](https://github.com/AOSSIE-Org/PictoPy/pull/978)) | ||
| - Face renaming via Enter key ([#581](https://github.com/AOSSIE-Org/PictoPy/pull/581)) | ||
| - Spawning and closing of backend and sync microservice from the Tauri app itself ([#1009](https://github.com/AOSSIE-Org/PictoPy/pull/1009)) | ||
| - Arch Linux AUR package with automated publishing workflow ([#1268](https://github.com/AOSSIE-Org/PictoPy/pull/1268)) | ||
| - AI models-based app size optimization ([#1263](https://github.com/AOSSIE-Org/PictoPy/pull/1263)) | ||
|
|
||
| ### Changed | ||
|
|
||
| - Streamlined Rust backend to a minimal API and updated docs structure ([#515](https://github.com/AOSSIE-Org/PictoPy/pull/515)) | ||
| - Extended hover activation hotspot for navigation arrows ([#702](https://github.com/AOSSIE-Org/PictoPy/pull/702)) | ||
| - Reversed marquee animation direction ([#894](https://github.com/AOSSIE-Org/PictoPy/pull/894)) | ||
| - Improved gallery hover interaction with hover delay and cursor cleanup ([#715](https://github.com/AOSSIE-Org/PictoPy/pull/715)) | ||
| - Switched backend setup to use Conda ([#975](https://github.com/AOSSIE-Org/PictoPy/pull/975)) | ||
| - Separated backend services and changed server port numbers ([#933](https://github.com/AOSSIE-Org/PictoPy/pull/933), [#934](https://github.com/AOSSIE-Org/PictoPy/pull/934)) | ||
| - Simplified Redux state ([#599](https://github.com/AOSSIE-Org/PictoPy/pull/599)) | ||
|
|
||
| ### Fixed | ||
|
|
||
| - Validated and sanitized image_ids in album APIs to prevent empty/invalid input and unsafe IN clauses ([#1253](https://github.com/AOSSIE-Org/PictoPy/pull/1253), [#629](https://github.com/AOSSIE-Org/PictoPy/pull/629)) | ||
| - Prevented InfoDialog from flickering to blue variant on close ([#630](https://github.com/AOSSIE-Org/PictoPy/pull/630)) | ||
| - Prevented duplicate scrollbars on Windows/Tauri ([#941](https://github.com/AOSSIE-Org/PictoPy/pull/941)) | ||
| - Enabled "Open Folder" button functionality ([#976](https://github.com/AOSSIE-Org/PictoPy/pull/976)) | ||
| - Fixed infinite recursion in InterceptHandler logging ([#940](https://github.com/AOSSIE-Org/PictoPy/pull/940)) | ||
| - Fixed Windows build not opening on first launch ([#922](https://github.com/AOSSIE-Org/PictoPy/pull/922)) | ||
| - Fixed macOS build not opening ([#659](https://github.com/AOSSIE-Org/PictoPy/pull/659)) | ||
| - Fixed progress bar overflow in onboarding steps ([#726](https://github.com/AOSSIE-Org/PictoPy/pull/726)) | ||
| - Improved face clustering accuracy with a similarity threshold ([#771](https://github.com/AOSSIE-Org/PictoPy/pull/771)) | ||
| - Fixed atomic DB operations and consistency in global reclustering ([#570](https://github.com/AOSSIE-Org/PictoPy/pull/570)) | ||
| - Fixed 500 error in the `/cluster_id/images` API ([#598](https://github.com/AOSSIE-Org/PictoPy/pull/598)) | ||
| - Fixed critical database connection leaks ([#547](https://github.com/AOSSIE-Org/PictoPy/pull/547)) | ||
| - Fixed database consistency on external image deletion events ([#520](https://github.com/AOSSIE-Org/PictoPy/pull/520)) | ||
| - Fixed "Open Original File" button in the image details panel ([#542](https://github.com/AOSSIE-Org/PictoPy/pull/542)) | ||
| - Fixed text overflow in the image details panel ([#537](https://github.com/AOSSIE-Org/PictoPy/pull/537)) | ||
| - Fixed oversized navbar height on first load ([#692](https://github.com/AOSSIE-Org/PictoPy/pull/692)) | ||
| - Fixed hover state and search bar UI issues ([#532](https://github.com/AOSSIE-Org/PictoPy/pull/532), [#529](https://github.com/AOSSIE-Org/PictoPy/pull/529)) | ||
| - Fixed image lock error ([#565](https://github.com/AOSSIE-Org/PictoPy/pull/565)) | ||
|
|
||
| ### Documentation | ||
|
|
||
| - Added CI check for markdown linting ([#1266](https://github.com/AOSSIE-Org/PictoPy/pull/1266)) | ||
| - Restructured intro page and sidebar navigation ([#1264](https://github.com/AOSSIE-Org/PictoPy/pull/1264)) | ||
| - Improved documentation site responsiveness on mobile devices ([#601](https://github.com/AOSSIE-Org/PictoPy/pull/601), [#763](https://github.com/AOSSIE-Org/PictoPy/pull/763)) | ||
| - Added Miniconda installation instructions to the Manual Setup Guide ([#971](https://github.com/AOSSIE-Org/PictoPy/pull/971)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use
grep -Ffor literal string matching to prevent regex injection.The grep pattern on line 25 treats
VERSIONas a regex pattern. If a release tag contains regex metacharacters (e.g.,v1.2.0.*, which Git allows), the pattern could match unintended CHANGELOG entries, bypassing the validation. Use the-Fflag to match the version string literally.🔒 Proposed fix for literal string matching
📝 Committable suggestion
🤖 Prompt for AI Agents