feat(packaging): add release package support
ci-release / verify (push) Failing after 3s
ci-release / publish-linux-amd64 (push) Has been skipped
ci-release / publish-arch-package (push) Has been skipped

This commit is contained in:
2026-08-07 08:56:23 +02:00
parent 83fa2d5276
commit c95d66d5aa
12 changed files with 253 additions and 3 deletions
+36
View File
@@ -11,6 +11,7 @@ name: ci-release
permissions: permissions:
contents: write contents: write
packages: write
jobs: jobs:
verify: verify:
@@ -144,3 +145,38 @@ jobs:
-H "Authorization: token ${GITEA_TOKEN}" \ -H "Authorization: token ${GITEA_TOKEN}" \
-F "attachment=@${asset}" -F "attachment=@${asset}"
done done
publish-arch-package:
if: startsWith(github.ref, 'refs/tags/v')
needs: verify
runs-on: [self-hosted, linux, arch, homelab]
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Build Arch package
shell: bash
run: |
set -euo pipefail
tag="${GITHUB_REF##*/}"
version="${tag#v}"
test "$version" = "$(tr -d '[:space:]' < VERSION)"
git archive --format=tar.gz --prefix="folderscope-${version}/" HEAD \
> "packaging/arch/folderscope-${version}.tar.gz"
(
cd packaging/arch
makepkg --syncdeps --noconfirm --force
)
- name: Publish to Gitea Arch registry
shell: bash
run: |
set -euo pipefail
package_file="$(find packaging/arch -maxdepth 1 -type f \
-name 'folderscope-*.pkg.tar.zst' -print -quit)"
test -n "$package_file"
curl --fail --show-error --user "${GITEA_ACTOR}:${GITEA_TOKEN}" \
--upload-file "$package_file" \
"https://gitea.forust.xyz/api/packages/forust/arch/folderscope"
+2
View File
@@ -1,6 +1,8 @@
/build/ /build/
/cmake-build-*/ /cmake-build-*/
/out/ /out/
/package/
/dist/
/.idea/ /.idea/
/.vscode/ /.vscode/
/CMakeLists.txt.user /CMakeLists.txt.user
+29 -3
View File
@@ -12,7 +12,7 @@ set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
find_package(Qt6 REQUIRED COMPONENTS Widgets Concurrent DBus) find_package(Qt6 REQUIRED COMPONENTS Widgets Concurrent DBus LinguistTools)
add_library(folderscope_core STATIC add_library(folderscope_core STATIC
src/search_core.cpp src/search_core.cpp
@@ -42,11 +42,37 @@ target_link_libraries(folderscope PRIVATE folderscope_core Qt6::Widgets Qt6::Con
target_compile_options(folderscope PRIVATE -Wall -Wextra -Wpedantic) target_compile_options(folderscope PRIVATE -Wall -Wextra -Wpedantic)
target_compile_definitions(folderscope PRIVATE FOLDERSCOPE_VERSION="${PROJECT_VERSION}") target_compile_definitions(folderscope PRIVATE FOLDERSCOPE_VERSION="${PROJECT_VERSION}")
qt_add_translations(folderscope
TS_FILES translations/folderscope_ru.ts
)
install(TARGETS folderscope RUNTIME DESTINATION bin) install(TARGETS folderscope RUNTIME DESTINATION bin)
install(FILES packaging/folderscope.desktop install(FILES packaging/org.folderscope.FolderScope.desktop
DESTINATION share/applications) DESTINATION share/applications)
install(FILES packaging/folderscope.svg install(FILES packaging/folderscope.svg
DESTINATION share/icons/hicolor/scalable/apps) DESTINATION share/icons/hicolor/scalable/apps
RENAME org.folderscope.FolderScope.svg)
install(FILES packaging/org.folderscope.FolderScope.metainfo.xml
DESTINATION share/metainfo)
install(FILES packaging/man/folderscope.1
DESTINATION share/man/man1)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/folderscope_ru.qm"
DESTINATION share/folderscope/translations)
set(CPACK_PACKAGE_NAME "folderscope")
set(CPACK_PACKAGE_VENDOR "FolderScope contributors")
set(CPACK_PACKAGE_CONTACT "FolderScope contributors")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Fast advanced file search for Linux")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set(CPACK_GENERATOR "DEB;RPM")
set(CPACK_DEBIAN_PACKAGE_SECTION "utils")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt6core6 (>= 6.2), libqt6widgets6 (>= 6.2), libqt6dbus6 (>= 6.2)")
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
set(CPACK_RPM_PACKAGE_GROUP "Applications/FileTools")
set(CPACK_RPM_PACKAGE_LICENSE "MIT")
set(CPACK_RPM_PACKAGE_AUTOREQPROV ON)
include(CPack)
include(CTest) include(CTest)
if (BUILD_TESTING) if (BUILD_TESTING)
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 FolderScope contributors
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.
+41
View File
@@ -49,6 +49,47 @@ Install into the current system:
cmake --install build cmake --install build
``` ```
## Packages
CPack produces native packages after a release build (the output is ignored by
Git):
```bash
cpack --config build/CPackConfig.cmake -B package
```
This creates `.deb` and `.rpm` packages. A Flatpak manifest is available at
`packaging/org.folderscope.FolderScope.yml`:
```bash
flatpak-builder --user --install --force-clean build-flatpak \
packaging/org.folderscope.FolderScope.yml
```
For Arch, use `packaging/arch/PKGBUILD` with a release tarball named
`folderscope-VERSION.tar.gz`.
Published releases are also available through the Gitea Arch package registry.
Import its signing key and add the following to `/etc/pacman.conf`:
```bash
curl -LO https://gitea.forust.xyz/api/packages/forust/arch/repository.key
sudo pacman-key --add repository.key
sudo pacman-key --lsign-key "$(gpg --show-keys --with-colons repository.key | awk -F: '/^fpr:/ {print $10; exit}')"
```
```ini
[folderscope]
SigLevel = Required
Server = https://gitea.forust.xyz/api/packages/forust/arch/$repo/$arch
```
Then install with `sudo pacman -Syu folderscope` (or `yay -S folderscope`).
Translations are Qt `.ts` files in `translations/`; CMake compiles and installs
their `.qm` files automatically. The application selects the system locale at
startup.
## Notes ## Notes
FolderScope targets Linux only. FolderScope targets Linux only.
+23
View File
@@ -0,0 +1,23 @@
pkgname=folderscope
pkgver=0.3.0
pkgrel=1
pkgdesc='Fast advanced file search for Linux'
arch=('x86_64')
url='https://gitea.forust.xyz/forust/folderscope'
license=('MIT')
depends=('qt6-base')
makedepends=('cmake' 'ninja')
source=("${pkgname}-${pkgver}.tar.gz")
sha256sums=('SKIP')
build() {
cmake -S "${srcdir}/${pkgname}-${pkgver}" -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF
cmake --build build
}
package() {
DESTDIR="${pkgdir}" cmake --install build
install -Dm644 "${srcdir}/${pkgname}-${pkgver}/LICENSE" \
"${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
}
+16
View File
@@ -0,0 +1,16 @@
.TH FOLDERSCOPE 1 "August 2026" "FolderScope" "User Commands"
.SH NAME
folderscope \- fast advanced file search for Linux
.SH SYNOPSIS
.B folderscope
.SH DESCRIPTION
.B FolderScope
is a graphical file-search application. It searches selected folders without
maintaining an index or background service. Results can be filtered, exported,
opened in a file manager, moved to the desktop Trash, or permanently deleted.
.SH FILES
.TP
.I ~/.config/FolderScope/FolderScope.conf
Per-user settings and search preferences, managed by Qt.
.SH AUTHORS
FolderScope contributors.
@@ -0,0 +1,8 @@
[Desktop Entry]
Type=Application
Name=FolderScope
Comment=Fast advanced file search
Exec=folderscope
Icon=org.folderscope.FolderScope
Terminal=false
Categories=Utility;FileTools;
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>org.folderscope.FolderScope</id>
<name>FolderScope</name>
<summary>Fast advanced file search</summary>
<metadata_license>MIT</metadata_license>
<project_license>MIT</project_license>
<description>
<p>Search files in selected folders without an index or background service.</p>
</description>
<launchable type="desktop-id">org.folderscope.FolderScope.desktop</launchable>
<provides><binary>folderscope</binary></provides>
<releases><release version="0.3.0" date="2026-08-07"/></releases>
</component>
+20
View File
@@ -0,0 +1,20 @@
app-id: org.folderscope.FolderScope
runtime: org.kde.Platform
runtime-version: '6.8'
sdk: org.kde.Sdk
command: folderscope
finish-args:
- --share=ipc
- --socket=fallback-x11
- --socket=wayland
- --device=dri
- --filesystem=home
modules:
- name: folderscope
buildsystem: cmake-ninja
config-opts:
- -DCMAKE_BUILD_TYPE=Release
- -DBUILD_TESTING=OFF
sources:
- type: dir
path: ..
+11
View File
@@ -1,7 +1,10 @@
#include <QApplication> #include <QApplication>
#include <QDir>
#include <QMetaType> #include <QMetaType>
#include <QLocale>
#include <QSettings> #include <QSettings>
#include <QTimer> #include <QTimer>
#include <QTranslator>
#include "main_window.h" #include "main_window.h"
#include "search_core.h" #include "search_core.h"
@@ -32,6 +35,14 @@ int main(int argc, char **argv)
QApplication app(argc, argv); QApplication app(argc, argv);
QCoreApplication::setOrganizationName(QStringLiteral("FolderScope")); QCoreApplication::setOrganizationName(QStringLiteral("FolderScope"));
QCoreApplication::setApplicationName(QStringLiteral("FolderScope")); QCoreApplication::setApplicationName(QStringLiteral("FolderScope"));
QTranslator translator;
const QString translationsPath = QDir(QCoreApplication::applicationDirPath())
.filePath(QStringLiteral("../share/folderscope/translations"));
if ((translator.load(QLocale(), QStringLiteral("folderscope"),
QStringLiteral("_"), translationsPath)
|| translator.load(QLocale(), QStringLiteral("folderscope"),
QStringLiteral("_"), QStringLiteral(":/i18n"))))
app.installTranslator(&translator);
migrateLegacySettings(); migrateLegacySettings();
QApplication::setStyle(QStringLiteral("Fusion")); QApplication::setStyle(QStringLiteral("Fusion"));
qRegisterMetaType<SearchOptions>(); qRegisterMetaType<SearchOptions>();
+32
View File
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="ru_RU">
<context>
<name>MainWindow</name>
<message><source>FolderScope</source><translation>FolderScope</translation></message>
<message><source>Search options</source><translation>Параметры поиска</translation></message>
<message><source>Stop</source><translation>Остановить</translation></message>
<message><source>Refresh</source><translation>Обновить</translation></message>
<message><source>Open</source><translation>Открыть</translation></message>
<message><source>Open folder</source><translation>Открыть папку</translation></message>
<message><source>Open With</source><translation>Открыть с помощью</translation></message>
<message><source>Move To Trash</source><translation>Переместить в корзину</translation></message>
<message><source>Delete Selected Files</source><translation>Удалить выбранные файлы</translation></message>
<message><source>Rename</source><translation>Переименовать</translation></message>
<message><source>Properties</source><translation>Свойства</translation></message>
<message><source>&amp;File</source><translation>&amp;Файл</translation></message>
<message><source>&amp;Edit</source><translation>&amp;Правка</translation></message>
<message><source>&amp;View</source><translation>&amp;Вид</translation></message>
<message><source>&amp;Options</source><translation>&amp;Настройки</translation></message>
<message><source>&amp;Help</source><translation>&amp;Справка</translation></message>
<message><source>Export</source><translation>Экспорт</translation></message>
<message><source>Find</source><translation>Найти</translation></message>
<message><source>Find next</source><translation>Найти далее</translation></message>
<message><source>Copy full filenames path</source><translation>Копировать полные пути</translation></message>
<message><source>Explorer Copy</source><translation>Копировать</translation></message>
<message><source>Explorer Cut</source><translation>Вырезать</translation></message>
<message><source>About</source><translation>О программе</translation></message>
<message><source>Move %1 selected item(s) to Trash?</source><translation>Переместить в корзину: %1 шт.?</translation></message>
<message><source>Failed to move %1 item(s) to Trash.</source><translation>Не удалось переместить в корзину: %1 шт.</translation></message>
</context>
</TS>