From 3bd6fa9c97f6e2cd3bc29eff7ea1e8370867ddfe Mon Sep 17 00:00:00 2001 From: Timi Date: Wed, 27 May 2026 15:09:39 +0800 Subject: [PATCH] add electron runner --- .gitignore | 2 - .serena/.gitignore | 2 + .serena/memories/project_overview.md | 5 + .serena/memories/style_and_conventions.md | 8 + .serena/memories/suggested_commands.md | 29 ++++ .serena/memories/task_completion_checklist.md | 7 + .serena/project.yml | 154 +++++++++++++++++ README.md | 36 ++++ gitea_runner_electron/.dockerignore | 4 + gitea_runner_electron/Dockerfile | 52 ++++++ gitea_runner_electron/README.md | 126 ++++++++++++++ .../build-electron-release.sh | 157 ++++++++++++++++++ 12 files changed, 580 insertions(+), 2 deletions(-) create mode 100644 .serena/.gitignore create mode 100644 .serena/memories/project_overview.md create mode 100644 .serena/memories/style_and_conventions.md create mode 100644 .serena/memories/suggested_commands.md create mode 100644 .serena/memories/task_completion_checklist.md create mode 100644 .serena/project.yml create mode 100644 gitea_runner_electron/.dockerignore create mode 100644 gitea_runner_electron/Dockerfile create mode 100644 gitea_runner_electron/README.md create mode 100644 gitea_runner_electron/build-electron-release.sh diff --git a/.gitignore b/.gitignore index 1a39e18..8771aa0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,2 @@ /AGENTS.md -/CLAUDE.md -/.claude /.idea diff --git a/.serena/.gitignore b/.serena/.gitignore new file mode 100644 index 0000000..2e510af --- /dev/null +++ b/.serena/.gitignore @@ -0,0 +1,2 @@ +/cache +/project.local.yml diff --git a/.serena/memories/project_overview.md b/.serena/memories/project_overview.md new file mode 100644 index 0000000..0495592 --- /dev/null +++ b/.serena/memories/project_overview.md @@ -0,0 +1,5 @@ +# 项目概览 + +这是一个 Docker 镜像源码集合仓库,位于 `E:\DockerProject\docker-files`。每个镜像通常独立一个目录,目录内包含 `Dockerfile` 和 `README.md`。根目录 `rebuild.sh` 根据目录名构建镜像,镜像名为 `timi/<目录名>`。 + +当前已有镜像包括 `gitea_runner_base`、`gitea_runner_node`、`gitea_runner_java`、`java_runtime`、`nginx`、`frp`、`vpower`。项目主要用于 Gitea Action Runner 和常用运行环境镜像。 \ No newline at end of file diff --git a/.serena/memories/style_and_conventions.md b/.serena/memories/style_and_conventions.md new file mode 100644 index 0000000..15ad753 --- /dev/null +++ b/.serena/memories/style_and_conventions.md @@ -0,0 +1,8 @@ +# 风格约定 + +- 使用中文沟通,文本文件使用 UTF-8 无 BOM。 +- Docker 镜像按目录组织,目录名即镜像名后缀。 +- Dockerfile 保持简单,优先复用已有基础镜像,如 `timi/gitea_runner_base:latest`。 +- README 使用中文说明用途、包含环境、构建命令和 Gitea Action 示例。 +- shell 脚本以 `#!/bin/bash` 和 `set -e` 为基础风格。 +- 不做无关重构,不改已有镜像除非任务明确要求。 \ No newline at end of file diff --git a/.serena/memories/suggested_commands.md b/.serena/memories/suggested_commands.md new file mode 100644 index 0000000..96abe8b --- /dev/null +++ b/.serena/memories/suggested_commands.md @@ -0,0 +1,29 @@ +# 常用命令 + +在 Windows PowerShell 中查看文件: + +```powershell +Get-ChildItem -Force +rg --files --hidden -g "!.git/**" +Get-Content -Path +``` + +构建镜像: + +```bash +./rebuild.sh gitea_runner_base +./rebuild.sh gitea_runner_node +./rebuild.sh [version] [save] +``` + +手动 Docker 构建: + +```bash +docker build -t timi/:latest ./ +``` + +查看 Git 状态: + +```powershell +git status --short +``` \ No newline at end of file diff --git a/.serena/memories/task_completion_checklist.md b/.serena/memories/task_completion_checklist.md new file mode 100644 index 0000000..96e7c60 --- /dev/null +++ b/.serena/memories/task_completion_checklist.md @@ -0,0 +1,7 @@ +# 完成任务检查 + +- 确认新增或修改的文件位于目标镜像目录中。 +- 确认 Dockerfile 和 README 文本为 UTF-8。 +- 需要时运行 `docker build -t timi/:latest ./` 校验镜像构建。 +- 如果构建会联网下载大量依赖,应先说明风险或等待用户确认。 +- 检查 `git status --short`,只报告本任务相关改动,不回滚用户已有改动。 \ No newline at end of file diff --git a/.serena/project.yml b/.serena/project.yml new file mode 100644 index 0000000..d92a33f --- /dev/null +++ b/.serena/project.yml @@ -0,0 +1,154 @@ +# the name by which the project can be referenced within Serena +project_name: "docker-files" + + +# list of languages for which language servers are started; choose from: +# al bash clojure cpp csharp +# csharp_omnisharp dart elixir elm erlang +# fortran fsharp go groovy haskell +# haxe java julia kotlin lua +# markdown +# matlab nix pascal perl php +# php_phpactor powershell python python_jedi r +# rego ruby ruby_solargraph rust scala +# swift terraform toml typescript typescript_vts +# vue yaml zig +# (This list may be outdated. For the current list, see values of Language enum here: +# https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py +# For some languages, there are alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.) +# Note: +# - For C, use cpp +# - For JavaScript, use typescript +# - For Free Pascal/Lazarus, use pascal +# Special requirements: +# Some languages require additional setup/installations. +# See here for details: https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers +# When using multiple languages, the first language server that supports a given file will be used for that file. +# The first language is the default language and the respective language server will be used as a fallback. +# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored. +languages: +- bash + +# the encoding used by text files in the project +# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings +encoding: "utf-8" + +# line ending convention to use when writing source files. +# Possible values: unset (use global setting), "lf", "crlf", or "native" (platform default) +# This does not affect Serena's own files (e.g. memories and configuration files), which always use native line endings. +line_ending: + +# The language backend to use for this project. +# If not set, the global setting from serena_config.yml is used. +# Valid values: LSP, JetBrains +# Note: the backend is fixed at startup. If a project with a different backend +# is activated post-init, an error will be returned. +language_backend: + +# whether to use project's .gitignore files to ignore files +ignore_all_files_in_gitignore: true + +# advanced configuration option allowing to configure language server-specific options. +# Maps the language key to the options. +# Have a look at the docstring of the constructors of the LS implementations within solidlsp (e.g., for C# or PHP) to see which options are available. +# No documentation on options means no options are available. +ls_specific_settings: {} + +# list of additional paths to ignore in this project. +# Same syntax as gitignore, so you can use * and **. +# Note: global ignored_paths from serena_config.yml are also applied additively. +ignored_paths: [] + +# whether the project is in read-only mode +# If set to true, all editing tools will be disabled and attempts to use them will result in an error +# Added on 2025-04-18 +read_only: false + +# list of tool names to exclude. +# This extends the existing exclusions (e.g. from the global configuration) +# +# Below is the complete list of tools for convenience. +# To make sure you have the latest list of tools, and to view their descriptions, +# execute `uv run scripts/print_tool_overview.py`. +# +# * `activate_project`: Activates a project based on the project name or path. +# * `check_onboarding_performed`: Checks whether project onboarding was already performed. +# * `create_text_file`: Creates/overwrites a file in the project directory. +# * `delete_memory`: Delete a memory file. Should only happen if a user asks for it explicitly, +# for example by saying that the information retrieved from a memory file is no longer correct +# or no longer relevant for the project. +# * `edit_memory`: Replaces content matching a regular expression in a memory. +# * `execute_shell_command`: Executes a shell command. +# * `find_file`: Finds files in the given relative paths +# * `find_referencing_symbols`: Finds symbols that reference the given symbol using the language server backend +# * `find_symbol`: Performs a global (or local) search using the language server backend. +# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes. +# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file. +# * `initial_instructions`: Provides instructions Serena usage (i.e. the 'Serena Instructions Manual') +# for clients that do not read the initial instructions when the MCP server is connected. +# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol. +# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol. +# * `list_dir`: Lists files and directories in the given directory (optionally with recursion). +# * `list_memories`: List available memories. Any memory can be read using the `read_memory` tool. +# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building). +# * `read_file`: Reads a file within the project directory. +# * `read_memory`: Read the content of a memory file. This tool should only be used if the information +# is relevant to the current task. You can infer whether the information +# is relevant from the memory file name. +# You should not read the same memory file multiple times in the same conversation. +# * `rename_memory`: Renames or moves a memory. Moving between project and global scope is supported +# (e.g., renaming "global/foo" to "bar" moves it from global to project scope). +# * `rename_symbol`: Renames a symbol throughout the codebase using language server refactoring capabilities. +# For JB, we use a separate tool. +# * `replace_content`: Replaces content in a file (optionally using regular expressions). +# * `replace_symbol_body`: Replaces the full definition of a symbol using the language server backend. +# * `safe_delete_symbol`: +# * `search_for_pattern`: Performs a search for a pattern in the project. +# * `write_memory`: Write some information (utf-8-encoded) about this project that can be useful for future tasks to a memory in md format. +# The memory name should be meaningful. +excluded_tools: [] + +# list of tools to include that would otherwise be disabled (particularly optional tools that are disabled by default). +# This extends the existing inclusions (e.g. from the global configuration). +included_optional_tools: [] + +# fixed set of tools to use as the base tool set (if non-empty), replacing Serena's default set of tools. +# This cannot be combined with non-empty excluded_tools or included_optional_tools. +fixed_tools: [] + +# list of mode names to that are always to be included in the set of active modes +# The full set of modes to be activated is base_modes + default_modes. +# If the setting is undefined, the base_modes from the global configuration (serena_config.yml) apply. +# Otherwise, this setting overrides the global configuration. +# Set this to [] to disable base modes for this project. +# Set this to a list of mode names to always include the respective modes for this project. +base_modes: + +# list of mode names that are to be activated by default. +# The full set of modes to be activated is base_modes + default_modes. +# If the setting is undefined, the default_modes from the global configuration (serena_config.yml) apply. +# Otherwise, this overrides the setting from the global configuration (serena_config.yml). +# This setting can, in turn, be overridden by CLI parameters (--mode). +default_modes: + +# initial prompt for the project. It will always be given to the LLM upon activating the project +# (contrary to the memories, which are loaded on demand). +initial_prompt: "" + +# time budget (seconds) per tool call for the retrieval of additional symbol information +# such as docstrings or parameter information. +# This overrides the corresponding setting in the global configuration; see the documentation there. +# If null or missing, use the setting from the global configuration. +symbol_info_budget: + +# list of regex patterns which, when matched, mark a memory entry as read‑only. +# Extends the list from the global configuration, merging the two lists. +read_only_memory_patterns: [] + +# list of regex patterns for memories to completely ignore. +# Matching memories will not appear in list_memories or activate_project output +# and cannot be accessed via read_memory or write_memory. +# To access ignored memory files, use the read_file tool on the raw file path. +# Extends the list from the global configuration, merging the two lists. +# Example: ["_archive/.*", "_episodes/.*"] +ignored_memory_patterns: [] diff --git a/README.md b/README.md index 6d1cd4b..f1eb119 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,17 @@ Gitea Action Runner Docker 镜像集合 docker build -t gitea_runner_base ./gitea_runner_base ``` +### gitea_runner_node + +基于 `gitea_runner_base` 的 Node.js 开发镜像,包含: + +- Node.js 18, 20, 22 +- npm, yarn, pnpm + +```bash +docker build -t gitea_runner_node ./gitea_runner_node +``` + ### gitea_runner_java 基于 `gitea_runner_base` 的 Java 开发镜像,包含: @@ -46,6 +57,27 @@ env: JAVA_HOME: /usr/lib/jvm/java-1.8-openjdk ``` +### gitea_runner_electron + +基于 `electronuserland/builder:wine` 的 Electron 三平台打包镜像,包含: + +- Node.js, npm, pnpm, yarn +- Wine,用于 Windows NSIS 打包 +- 7zip, zip, unzip 等压缩工具 +- `build-electron-release` 三平台打包脚本 + +默认打包目标: + +- Linux: AppImage x64 +- Windows: NSIS x64 +- macOS: zip x64 + arm64 + +macOS 只生成 zip,不处理 dmg、签名和公证。 + +```bash +docker build -t gitea_runner_electron ./gitea_runner_electron +``` + ## 构建顺序 ```bash @@ -53,5 +85,9 @@ env: docker build -t gitea_runner_base ./gitea_runner_base # 2. 再构建语言环境镜像 +docker build -t gitea_runner_node ./gitea_runner_node docker build -t gitea_runner_java ./gitea_runner_java + +# 3. Electron 镜像基于官方 Wine 镜像,可独立构建 +docker build -t gitea_runner_electron ./gitea_runner_electron ``` diff --git a/gitea_runner_electron/.dockerignore b/gitea_runner_electron/.dockerignore new file mode 100644 index 0000000..8323de4 --- /dev/null +++ b/gitea_runner_electron/.dockerignore @@ -0,0 +1,4 @@ +* +!Dockerfile +!build-electron-release.sh +!README.md diff --git a/gitea_runner_electron/Dockerfile b/gitea_runner_electron/Dockerfile new file mode 100644 index 0000000..dfb2487 --- /dev/null +++ b/gitea_runner_electron/Dockerfile @@ -0,0 +1,52 @@ +# Gitea Action Runner Electron Image +# 用于 Electron Linux AppImage、Windows NSIS、macOS zip 打包 + +FROM electronuserland/builder:wine + +LABEL maintainer="www.imyeyu.com" +LABEL description="Gitea Action Runner for Electron Linux AppImage, Windows NSIS and macOS zip packaging" + +ENV CI=true +ENV ELECTRON_CACHE=/root/.cache/electron +ENV ELECTRON_BUILDER_CACHE=/root/.cache/electron-builder +ENV PNPM_HOME=/usr/local/share/pnpm +ENV PATH="${PNPM_HOME}:${PATH}" + +ARG PNPM_VERSION=10 + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + bash \ + ca-certificates \ + curl \ + g++ \ + git \ + jq \ + make \ + openssh-client \ + p7zip-full \ + python3 \ + rsync \ + unzip \ + xz-utils \ + zip; \ + npm install -g "pnpm@${PNPM_VERSION}" yarn; \ + pnpm config set store-dir /pnpm/store; \ + mkdir -p \ + /pnpm/store \ + "${ELECTRON_CACHE}" \ + "${ELECTRON_BUILDER_CACHE}" \ + /workspace; \ + apt-get clean; \ + rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +COPY build-electron-release.sh /usr/local/bin/build-electron-release + +RUN chmod +x /usr/local/bin/build-electron-release \ + && node --version \ + && npm --version \ + && pnpm --version \ + && wine --version + +WORKDIR /workspace diff --git a/gitea_runner_electron/README.md b/gitea_runner_electron/README.md new file mode 100644 index 0000000..055b455 --- /dev/null +++ b/gitea_runner_electron/README.md @@ -0,0 +1,126 @@ +# Gitea Runner Electron + +Electron 三平台打包镜像,用于 Gitea Actions 中构建桌面端发布产物。 + +## 基础镜像 + +- `electronuserland/builder:wine` + +## 包含环境 + +| 组件 | 说明 | +|------|------| +| Node.js | 由基础镜像提供 | +| npm | 由基础镜像提供 | +| pnpm | 默认安装 `pnpm@10`,可通过构建参数覆盖 | +| yarn | 全局安装 | +| Wine | 用于 Windows NSIS 打包 | +| 7zip/zip/unzip | 用于压缩和 Electron Builder 产物处理 | +| python3/make/g++ | 用于可能存在的 Node.js 原生依赖编译 | + +## 打包目标 + +| 平台 | Electron Builder 目标 | 输出目录 | +|------|------------------------|----------| +| Linux | `AppImage --x64` | `release/linux` | +| Windows | `nsis --x64` | `release/windows` | +| macOS | `zip --x64 --arm64` | `release/macos` | + +macOS 这里只生成 zip,不处理 dmg、签名和公证。Linux 容器里强行做 macOS 完整发布流程是错方向。 + +## 构建镜像 + +```bash +./rebuild.sh gitea_runner_electron +``` + +指定 pnpm 主版本: + +```bash +docker build --build-arg PNPM_VERSION=10 -t timi/gitea_runner_electron:latest ./gitea_runner_electron +``` + +## 打包脚本 + +镜像内置命令: + +```bash +build-electron-release +``` + +默认行为: + +1. 根据锁文件自动选择包管理器 +2. 安装依赖 +3. 执行 `vite build` +4. 构建 Linux AppImage +5. 构建 Windows NSIS +6. 构建 macOS zip + +常用参数: + +```bash +build-electron-release --no-install +build-electron-release --target linux,windows +build-electron-release --target macos --no-renderer +build-electron-release --release-dir release +``` + +也可以通过环境变量控制: + +```bash +PACKAGE_MANAGER=pnpm ELECTRON_TARGETS=linux,windows,macos RELEASE_DIR=release build-electron-release +``` + +## Gitea Actions 示例 + +如果 runner 标签已经映射到该镜像: + +```yaml +jobs: + release: + runs-on: act_runner_electron + env: + CSC_IDENTITY_AUTO_DISCOVERY: "false" + ELECTRON_CACHE: .cache/electron + ELECTRON_BUILDER_CACHE: .cache/electron-builder + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Build Release + run: build-electron-release +``` + +如果使用 job container: + +```yaml +jobs: + release: + runs-on: act_runner_node + container: + image: timi/gitea_runner_electron:latest + env: + CSC_IDENTITY_AUTO_DISCOVERY: "false" + ELECTRON_CACHE: .cache/electron + ELECTRON_BUILDER_CACHE: .cache/electron-builder + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Build Release + run: build-electron-release +``` + +已有项目如果需要先写入版本号,可以继续拆步骤: + +```yaml +- name: Install Frontend Dependencies + run: pnpm install --frozen-lockfile + +- name: Write Release Version + run: npm version "$RELEASE_VERSION" --no-git-tag-version --allow-same-version + +- name: Build Release + run: build-electron-release --no-install +``` diff --git a/gitea_runner_electron/build-electron-release.sh b/gitea_runner_electron/build-electron-release.sh new file mode 100644 index 0000000..f6935a1 --- /dev/null +++ b/gitea_runner_electron/build-electron-release.sh @@ -0,0 +1,157 @@ +#!/bin/bash + +set -euo pipefail + +usage() { + cat <<'EOF' +Usage: build-electron-release [options] + +Options: + --no-install 跳过依赖安装 + --no-renderer 跳过 vite build + --target 打包目标,默认 linux,windows,macos + 可用值:linux,windows,win,macos,mac,darwin + --release-dir 输出目录,默认 release + -h, --help 显示帮助 + +Environment: + PACKAGE_MANAGER 指定包管理器:pnpm、npm、yarn + ELECTRON_TARGETS 同 --target + RELEASE_DIR 同 --release-dir +EOF +} + +install_deps=true +build_renderer=true +targets="${ELECTRON_TARGETS:-linux,windows,macos}" +release_dir="${RELEASE_DIR:-release}" +package_manager="${PACKAGE_MANAGER:-}" + +while [ "$#" -gt 0 ]; do + case "$1" in + --no-install) + install_deps=false + ;; + --no-renderer) + build_renderer=false + ;; + --target) + shift + if [ "$#" -lt 1 ]; then + echo "缺少 --target 参数值" >&2 + exit 1 + fi + targets="$1" + ;; + --release-dir) + shift + if [ "$#" -lt 1 ]; then + echo "缺少 --release-dir 参数值" >&2 + exit 1 + fi + release_dir="$1" + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "未知参数:$1" >&2 + usage >&2 + exit 1 + ;; + esac + shift +done + +detect_package_manager() { + if [ -n "$package_manager" ]; then + echo "$package_manager" + return + fi + + if [ -f pnpm-lock.yaml ]; then + echo "pnpm" + return + fi + + if [ -f yarn.lock ]; then + echo "yarn" + return + fi + + echo "npm" +} + +pm="$(detect_package_manager)" + +install_project_deps() { + case "$pm" in + pnpm) + pnpm install --frozen-lockfile + ;; + npm) + npm ci + ;; + yarn) + yarn install --frozen-lockfile + ;; + *) + echo "不支持的包管理器:$pm" >&2 + exit 1 + ;; + esac +} + +run_local_bin() { + case "$pm" in + pnpm) + pnpm exec "$@" + ;; + npm) + npx --no-install "$@" + ;; + yarn) + yarn exec "$@" + ;; + esac +} + +has_target() { + local target="$1" + local item + local normalized_targets + + normalized_targets="$(echo "$targets" | tr 'A-Z' 'a-z' | tr -d ' ')" + IFS=',' read -ra items <<< "$normalized_targets" + + for item in "${items[@]}"; do + case "$item:$target" in + linux:linux|windows:windows|win:windows|macos:macos|mac:macos|darwin:macos) + return 0 + ;; + esac + done + + return 1 +} + +if $install_deps; then + install_project_deps +fi + +if $build_renderer; then + run_local_bin vite build +fi + +if has_target linux; then + run_local_bin electron-builder --linux AppImage --x64 --publish never --config.directories.output="${release_dir}/linux" +fi + +if has_target windows; then + run_local_bin electron-builder --win nsis --x64 --publish never --config.directories.output="${release_dir}/windows" +fi + +if has_target macos; then + run_local_bin electron-builder --mac zip --x64 --arm64 --publish never --config.directories.output="${release_dir}/macos" +fi