Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
cfd1ebe
🔧 Update README with new features and demo gif positioning
Slowhand0309 Aug 7, 2025
5603043
Create LICENSE
Slowhand0309 Aug 11, 2025
d0db9d1
🔧 Add Sparkle auto-update framework dependency
Slowhand0309 Aug 13, 2025
5e80b8c
🔧 Add Info.plist for Sparkle auto-update configuration
Slowhand0309 Aug 13, 2025
5c29b97
🔧 Add SUFeedURL to Info.plist for Sparkle auto-update
Slowhand0309 Aug 13, 2025
28f1b0a
🔧 Add Sparkle auto-update entitlements and installer service configur…
Slowhand0309 Aug 16, 2025
154644f
🔧 Add network client entitlement for Sparkle auto-update
Slowhand0309 Aug 16, 2025
27018d6
🔧 Add Sparkle auto-update menu item and AppUpdater implementation
Slowhand0309 Aug 16, 2025
0964a37
🔧 Add gentle update notifications and Sparkle delegate implementation
Slowhand0309 Aug 17, 2025
3f0ed11
🔧 Rename UpdaterDelegate property from gentleDelegate to delegate
Slowhand0309 Aug 17, 2025
63cf344
Merge pull request #51 from Slowhand0309/feature/auto-update
Slowhand0309 Aug 18, 2025
c98b3bb
✨ Add multiple selection support to shelf items list
Slowhand0309 Aug 20, 2025
bb040e3
Merge pull request #53 from Slowhand0309/feature/multiple-selections
Slowhand0309 Aug 20, 2025
51ae395
✨ Add file preview functionality with QuickLook integration
Slowhand0309 Aug 21, 2025
2d17b4f
✨ Add side panel preview with floating window support
Slowhand0309 Aug 26, 2025
358c3a8
🔧 Fix layout by adding Spacer to align preview button in shelf item view
Slowhand0309 Aug 26, 2025
627527f
Merge pull request #54 from Slowhand0309/feature/enable-preview
Slowhand0309 Aug 26, 2025
341df6e
🔧 Add build workflow and refactor release CI for artifact generation
Slowhand0309 Aug 27, 2025
90cfe7f
Merge pull request #55 from Slowhand0309/fix/create-release-ci
Slowhand0309 Aug 27, 2025
84f7ed1
🔧 Improve side panel preview positioning with left-side anchor and sc…
Slowhand0309 Aug 27, 2025
30d9150
✨ Add preview position setting with left/right side selection support
Slowhand0309 Aug 27, 2025
87a36cf
Merge pull request #57 from Slowhand0309/feature/preview-position
Slowhand0309 Aug 27, 2025
e3a3060
🎯 Bump version to v0.1.0 and update project version for release
Slowhand0309 Aug 27, 2025
ba58daa
Merge pull request #58 from Slowhand0309/release/v0.1.0
Slowhand0309 Aug 27, 2025
524ae1e
📝 Update README badges and demo GIF for enhanced project presentation
Slowhand0309 Aug 27, 2025
2effa13
Merge pull request #59 from Slowhand0309/fix/doc
Slowhand0309 Aug 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions .github/workflows/create-release-with-artifact.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
name: build-macos
on:
push:
# Not used once the Drop is rejected in the released binary for some reason.
# tags: ["v*"]
branches:
- check/ci

permissions:
contents: write

jobs:
build-sign-notarize:
runs-on: macos-15

steps:
- uses: actions/checkout@v4

# Import certificates into Keychain
- uses: apple-actions/import-codesign-certs@v3
with:
p12-file-base64: ${{ secrets.DEV_ID_CERT_P12 }}
p12-password: ${{ secrets.DEV_ID_CERT_PASSWORD }}

# Xcode build (signed)
- name: Build release
run: |
xcodebuild -project QuickShelf.xcodeproj \
-scheme QuickShelf \
-config Release \
-archivePath build/QuickShelf.xcarchive \
clean archive \
ARCHS="arm64 x86_64" \
ONLY_ACTIVE_ARCH=NO
env:
TEAM_ID: ${{ secrets.TEAM_ID }}

- name: Codesign
run: |
xcrun codesign --force --deep \
--timestamp \
--options runtime \
--entitlements QuickShelf/QuickShelf.entitlements \
--sign "$SIGN_ID" "build/QuickShelf.xcarchive/Products/Applications/QuickShelf.app"
env:
TEAM_ID: ${{ secrets.TEAM_ID }}
SIGN_ID: ${{ secrets.DEVID_COMMON_NAME }}
# ZIP the .app
- name: Zip app
run: |
ditto -c -k --keepParent "build/QuickShelf.xcarchive/Products/Applications/QuickShelf.app" QuickShelf.zip

# Submit with notarytool (save Keychain profile on the fly)
- name: Store notary credentials
run: |
xcrun notarytool store-credentials "notary-profile" \
--apple-id "$APPLE_ID" \
--team-id "$TEAM_ID" \
--password "$APPLE_PASS"
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASS: ${{ secrets.APPLE_PASS }}
TEAM_ID: ${{ secrets.TEAM_ID }}

- name: Submit to notarization
run: |
xcrun notarytool submit QuickShelf.zip \
--keychain-profile "notary-profile" --wait

# Staple
- name: Staple ticket
run: xcrun stapler staple "build/QuickShelf.xcarchive/Products/Applications/QuickShelf.app"

# Gatekeeper verification and re-zipping
- name: Validate
run: |
spctl --assess --type execute --verbose=4 "build/QuickShelf.xcarchive/Products/Applications/QuickShelf.app"
xcrun stapler validate "build/QuickShelf.xcarchive/Products/Applications/QuickShelf.app"
ditto -c -k --keepParent "build/QuickShelf.xcarchive/Products/Applications/QuickShelf.app" QuickShelf.zip

# - name: Create Release and Upload Assets
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# uses: softprops/action-gh-release@v2
# with:
# files: QuickShelf.zip
# draft: true
# generate_release_notes: true

# Upload Deliverables
- uses: actions/upload-artifact@v4
with:
name: QuickShelf-macOS
path: QuickShelf.zip
103 changes: 14 additions & 89 deletions .github/workflows/create-release.yml
Original file line number Diff line number Diff line change
@@ -1,94 +1,19 @@
name: build-macos
name: create-release

on:
push:
# Not used once the Drop is rejected in the released binary for some reason.
# tags: ["v*"]
branches:
- check/ci

permissions:
contents: write
tags: ["v*"]

jobs:
build-sign-notarize:
runs-on: macos-15

build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

# Import certificates into Keychain
- uses: apple-actions/import-codesign-certs@v3
with:
p12-file-base64: ${{ secrets.DEV_ID_CERT_P12 }}
p12-password: ${{ secrets.DEV_ID_CERT_PASSWORD }}

# Xcode build (signed)
- name: Build release
run: |
xcodebuild -project QuickShelf.xcodeproj \
-scheme QuickShelf \
-config Release \
-archivePath build/QuickShelf.xcarchive \
clean archive \
ARCHS="arm64 x86_64" \
ONLY_ACTIVE_ARCH=NO
env:
TEAM_ID: ${{ secrets.TEAM_ID }}

- name: Codesign
run: |
xcrun codesign --force --deep \
--timestamp \
--options runtime \
--entitlements QuickShelf/QuickShelf.entitlements \
--sign "$SIGN_ID" "build/QuickShelf.xcarchive/Products/Applications/QuickShelf.app"
env:
TEAM_ID: ${{ secrets.TEAM_ID }}
SIGN_ID: ${{ secrets.DEVID_COMMON_NAME }}
# ZIP the .app
- name: Zip app
run: |
ditto -c -k --keepParent "build/QuickShelf.xcarchive/Products/Applications/QuickShelf.app" QuickShelf.zip

# Submit with notarytool (save Keychain profile on the fly)
- name: Store notary credentials
run: |
xcrun notarytool store-credentials "notary-profile" \
--apple-id "$APPLE_ID" \
--team-id "$TEAM_ID" \
--password "$APPLE_PASS"
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASS: ${{ secrets.APPLE_PASS }}
TEAM_ID: ${{ secrets.TEAM_ID }}

- name: Submit to notarization
run: |
xcrun notarytool submit QuickShelf.zip \
--keychain-profile "notary-profile" --wait

# Staple
- name: Staple ticket
run: xcrun stapler staple "build/QuickShelf.xcarchive/Products/Applications/QuickShelf.app"

# Gatekeeper verification and re-zipping
- name: Validate
run: |
spctl --assess --type execute --verbose=4 "build/QuickShelf.xcarchive/Products/Applications/QuickShelf.app"
xcrun stapler validate "build/QuickShelf.xcarchive/Products/Applications/QuickShelf.app"
ditto -c -k --keepParent "build/QuickShelf.xcarchive/Products/Applications/QuickShelf.app" QuickShelf.zip

# - name: Create Release and Upload Assets
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# uses: softprops/action-gh-release@v2
# with:
# files: QuickShelf.zip
# draft: true
# generate_release_notes: true

# Upload Deliverables
- uses: actions/upload-artifact@v4
with:
name: QuickShelf-macOS
path: QuickShelf.zip
- name: Checkout
uses: actions/checkout@v5
- name: Create draft release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: softprops/action-gh-release@v2
with:
draft: true
generate_release_notes: true
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2025 SlowLab

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
40 changes: 36 additions & 4 deletions QuickShelf.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
6B31AE332E43FF0600C4653D /* LaunchAtLogin in Frameworks */ = {isa = PBXBuildFile; productRef = 6B31AE322E43FF0600C4653D /* LaunchAtLogin */; };
6B3437242E3B6B4F00C52D3C /* KeyboardShortcuts in Frameworks */ = {isa = PBXBuildFile; productRef = 6B3437232E3B6B4F00C52D3C /* KeyboardShortcuts */; };
6B400A802E174A6E00505989 /* MenuBarExtraAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 6B400A7F2E174A6E00505989 /* MenuBarExtraAccess */; };
6B5A8B6B2E4D281A00E1293D /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 6B5A8B6A2E4D281A00E1293D /* Sparkle */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand All @@ -35,9 +36,22 @@
6B400A6B2E1749FC00505989 /* QuickShelfUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = QuickShelfUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */

/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
6B5A8BDC2E4D357900E1293D /* Exceptions for "QuickShelf" folder in "QuickShelf" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
Info.plist,
);
target = 6B400A522E1749FB00505989 /* QuickShelf */;
};
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */

/* Begin PBXFileSystemSynchronizedRootGroup section */
6B400A552E1749FB00505989 /* QuickShelf */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
6B5A8BDC2E4D357900E1293D /* Exceptions for "QuickShelf" folder in "QuickShelf" target */,
);
path = QuickShelf;
sourceTree = "<group>";
};
Expand All @@ -59,6 +73,7 @@
buildActionMask = 2147483647;
files = (
6B31AE332E43FF0600C4653D /* LaunchAtLogin in Frameworks */,
6B5A8B6B2E4D281A00E1293D /* Sparkle in Frameworks */,
6B400A802E174A6E00505989 /* MenuBarExtraAccess in Frameworks */,
6B3437242E3B6B4F00C52D3C /* KeyboardShortcuts in Frameworks */,
);
Expand Down Expand Up @@ -124,6 +139,7 @@
6B400A7F2E174A6E00505989 /* MenuBarExtraAccess */,
6B3437232E3B6B4F00C52D3C /* KeyboardShortcuts */,
6B31AE322E43FF0600C4653D /* LaunchAtLogin */,
6B5A8B6A2E4D281A00E1293D /* Sparkle */,
);
productName = QuickShelf;
productReference = 6B400A532E1749FB00505989 /* QuickShelf.app */;
Expand Down Expand Up @@ -211,6 +227,7 @@
6B400A7E2E174A6E00505989 /* XCRemoteSwiftPackageReference "MenuBarExtraAccess" */,
6B3437222E3B6B4F00C52D3C /* XCRemoteSwiftPackageReference "KeyboardShortcuts" */,
6B31AE312E43FF0600C4653D /* XCRemoteSwiftPackageReference "LaunchAtLogin-Modern" */,
6B5A8B692E4D281A00E1293D /* XCRemoteSwiftPackageReference "Sparkle" */,
);
preferredProjectObjectVersion = 77;
productRefGroup = 6B400A542E1749FB00505989 /* Products */;
Expand Down Expand Up @@ -412,18 +429,19 @@
CODE_SIGN_ENTITLEMENTS = QuickShelf/QuickShelf.entitlements;
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = QuickShelf/Info.plist;
INFOPLIST_KEY_LSUIElement = YES;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 14.6;
MARKETING_VERSION = 0.0.9;
MARKETING_VERSION = 0.1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.slowlab.QuickShelf;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand All @@ -441,18 +459,19 @@
CODE_SIGN_ENTITLEMENTS = QuickShelf/QuickShelf.entitlements;
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = QuickShelf/Info.plist;
INFOPLIST_KEY_LSUIElement = YES;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 14.6;
MARKETING_VERSION = 0.0.9;
MARKETING_VERSION = 0.1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.slowlab.QuickShelf;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down Expand Up @@ -592,6 +611,14 @@
minimumVersion = 1.2.1;
};
};
6B5A8B692E4D281A00E1293D /* XCRemoteSwiftPackageReference "Sparkle" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/sparkle-project/Sparkle";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 2.7.1;
};
};
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
Expand All @@ -610,6 +637,11 @@
package = 6B400A7E2E174A6E00505989 /* XCRemoteSwiftPackageReference "MenuBarExtraAccess" */;
productName = MenuBarExtraAccess;
};
6B5A8B6A2E4D281A00E1293D /* Sparkle */ = {
isa = XCSwiftPackageProductDependency;
package = 6B5A8B692E4D281A00E1293D /* XCRemoteSwiftPackageReference "Sparkle" */;
productName = Sparkle;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 6B400A4B2E1749FB00505989 /* Project object */;
Expand Down
Loading