Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
e029e3a
feat: add a version registry that keeps release lists between runs
roxblnfk Sep 12, 2026
ea36d7e
fix: recover from releases deleted after the version registry stored …
roxblnfk Sep 12, 2026
afeaa29
fix: drop releases deleted upstream when the version registry checks …
roxblnfk Sep 14, 2026
d1b559e
feat(cache:clear): ask before dropping the whole registry
roxblnfk Sep 14, 2026
3c49450
chore(psalm): make the static analysis pass on the version registry code
roxblnfk Sep 14, 2026
86d6b00
test: cover the registry paths the first tests passed trivially
roxblnfk Sep 14, 2026
244e38f
feat(registry): store the asset digest reported by GitHub
roxblnfk Sep 14, 2026
73efb91
feat(registry): split release lists into segments read on demand
roxblnfk Sep 14, 2026
90ffe6e
fix(config): let the environment override `dload.xml` and the command…
roxblnfk Sep 14, 2026
752d3ad
fix(registry): key the registry by the path the repository reports, n…
roxblnfk Sep 15, 2026
70c433c
fix(registry): keep the stored list when the source cannot read a rel…
roxblnfk Sep 15, 2026
0df4e1c
fix(github): send the API token to GitHub hosts only
roxblnfk Sep 15, 2026
aaa2604
fix(registry): keep GitHub drafts as hidden placeholders so the store…
roxblnfk Sep 15, 2026
a023166
fix(registry): hold a lock on the repository while its files are save…
roxblnfk Sep 15, 2026
3a1ed0b
test: cover the downloader, repository adapters and registry paths th…
roxblnfk Sep 15, 2026
8444eef
test(registry): make the failed-rename test hold the target directory…
roxblnfk Sep 15, 2026
b74ae4d
feat(get): add `-r` as the short form of `--refresh`
roxblnfk Sep 15, 2026
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
71 changes: 71 additions & 0 deletions README-es.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Con DLoad puedes:
- [Tipos de Descarga](#tipos-de-descarga)
- [Restricciones de Versión](#restricciones-de-versión)
- [Opciones de Configuración Avanzadas](#opciones-de-configuración-avanzadas)
- [Registro de Versiones](#registro-de-versiones)
- [Construir RoadRunner Personalizado](#construir-roadrunner-personalizado)
- [Configuración de Acción de Construcción](#configuración-de-acción-de-construcción)
- [Atributos de Acción Velox](#atributos-de-acción-velox)
Expand Down Expand Up @@ -172,6 +173,7 @@ También puedes descargar la versión más reciente desde [GitHub releases](http
| `--stability` | Estabilidad del release (stable, beta) | stable |
| `--config` | Ruta al archivo de configuración | ./dload.xml |
| `--force`, `-f` | Forzar descarga aunque el binario ya exista | false |
| `--refresh`, `-r` | Comprobar si hay nuevos releases aunque el registro de versiones siga vigente | false |

### Ver Software

Expand Down Expand Up @@ -348,6 +350,75 @@ Usa restricciones de versión estilo Composer:
</dload>
```

### Registro de Versiones

Resolver una versión significa pedir a GitHub o GitLab la lista de releases del repositorio. DLoad
guarda lo que aprende en un **registro de versiones** local: una pequeña base de datos con los releases
y assets de cada repositorio conocido, un archivo JSON por repositorio. Las versiones nunca expiran.
Lo que expira es la *última comprobación* del repositorio: mientras sea más reciente que `cache-ttl`,
`dload get` se responde desde el registro sin una sola petición a la API. Cuando es más antigua, DLoad
pide a la API solo los releases publicados desde entonces, normalmente una única petición.

Las páginas de releases se siguen cargando de forma perezosa. La primera ejecución obtiene solo las
páginas necesarias para encontrar un release que cumpla la versión pedida; los releases más antiguos se
cargan después, bajo demanda.

El registro está activado por defecto y vive en el directorio de caché del usuario
(`$XDG_CACHE_HOME/dload`, `%LOCALAPPDATA%\dload\cache` en Windows, `~/.cache/dload` en otros casos):

```xml
<dload temp-dir="./runtime" cache-dir="./runtime/dload-cache" cache-ttl="3600">
<actions>
<download software="rr" />
</actions>
</dload>
```

| Atributo | Variable de entorno | Por defecto | Significado |
|-------------|---------------------|--------------------------------|--------------------------------------------------------------------------------------|
| `cache-dir` | `DLOAD_CACHE_DIR` | directorio de caché del usuario | Directorio del registro de versiones. |
| `cache-ttl` | `DLOAD_CACHE_TTL` | `600` | Segundos que sigue siendo válida la última comprobación. `0` desactiva el registro. |

La variable de entorno tiene prioridad sobre el atributo de `dload.xml`, y la opción de línea de comandos sobre ambos.

```bash
# Comprobar si hay nuevos releases aunque la última comprobación siga vigente
./vendor/bin/dload get rr --refresh

# Olvidar los repositorios de un software, o todo el registro
./vendor/bin/dload cache:clear rr
./vendor/bin/dload cache:clear --force
```

> [!NOTE]
> El registro solo contiene metadatos de releases: tags, nombres y enlaces de descarga. Las descargas
> no pasan por él y nunca guarda credenciales, así que el directorio puede compartirse o guardarse en
> la caché de CI sin problemas. Si una comprobación falla por un error de red o un límite de la API, se
> usan los releases almacenados; un repositorio nunca visto sigue fallando de forma visible. Un
> release almacenado cuyos assets desaparecieron del origen se elimina del registro en cuanto falla
> su descarga, y la lista de releases se vuelve a obtener antes de que la ejecución se dé por vencida.
> Los borradores de releases de GitHub nunca se entregan; el registro guarda solo sus etiquetas como marcadores ocultos que conservan la posición en la lista. Un release que el proveedor inserta por debajo del inicio de su lista, como un release de GitLab con un `released_at` retroactivo, no lo detecta la comprobación; ejecute `cache:clear` para ese software para incorporarlo.

En GitHub Actions el directorio puede conservarse entre ejecuciones del workflow, de modo que cada
ejecución gasta el límite de la API solo en los releases publicados desde la anterior:

```yaml
- name: Restore DLoad version registry
uses: actions/cache@v4
with:
path: ./runtime/dload-cache
key: dload-registry-${{ github.run_id }}
restore-keys: dload-registry-

- run: ./vendor/bin/dload get
env:
DLOAD_CACHE_DIR: ./runtime/dload-cache
```

El `github.run_id` en la clave hace que cada ejecución guarde su registro, y `restore-keys` permite
que la siguiente parta del más reciente. Los jobs paralelos de un mismo workflow no ven la caché de los
demás, ya que `actions/cache` la guarda al terminar cada job.

## Construir RoadRunner Personalizado

DLoad soporta la construcción de binarios personalizados de RoadRunner usando la herramienta Velox. Esto es útil cuando necesitas RoadRunner con combinaciones específicas de plugins que no están disponibles en las versiones pre-construidas.
Expand Down
72 changes: 72 additions & 0 deletions README-ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ DLoad решает распространённую проблему в PHP-пр
- [Типы загрузки](#типы-загрузки)
- [Ограничения версий](#ограничения-версий)
- [Расширенные настройки](#расширенные-настройки)
- [Реестр версий](#реестр-версий)
- [Сборка кастомного RoadRunner](#сборка-кастомного-roadrunner)
- [Настройка действия сборки](#настройка-действия-сборки)
- [Атрибуты Velox-действия](#атрибуты-velox-действия)
Expand Down Expand Up @@ -173,6 +174,7 @@ composer require internal/dload -W
| `--stability` | Стабильность релиза (stable, beta) | stable |
| `--config` | Путь к конфигурационному файлу | ./dload.xml |
| `--force`, `-f` | Принудительная загрузка даже если бинарник уже есть | false |
| `--refresh`, `-r` | Проверить репозитории на новые релизы, даже если реестр версий ещё свежий | false |

### Просмотр ПО

Expand Down Expand Up @@ -349,6 +351,76 @@ DLoad поддерживает три типа загрузки, которые
</dload>
```

### Реестр версий

Чтобы определить версию, DLoad запрашивает у GitHub или GitLab список релизов репозитория. Всё,
что он узнаёт, сохраняется в локальном **реестре версий**: небольшой базе релизов и ассетов каждого
известного репозитория, по одному JSON-файлу на репозиторий. Версии из реестра не устаревают.
Устаревает только *последняя проверка* репозитория: пока она моложе `cache-ttl`, `dload get`
отвечает из реестра без единого запроса к API. Когда проверка устарела, DLoad запрашивает у API
только релизы, вышедшие после неё, и обычно это один запрос.

Страницы релизов по-прежнему загружаются лениво. Первый запуск получает столько страниц, сколько
нужно, чтобы найти релиз под запрошенную версию, а более старые релизы догружаются позже, по мере
надобности.

Реестр включён по умолчанию и живёт в пользовательском каталоге кэша (`$XDG_CACHE_HOME/dload`,
`%LOCALAPPDATA%\dload\cache` в Windows, иначе `~/.cache/dload`):

```xml
<dload temp-dir="./runtime" cache-dir="./runtime/dload-cache" cache-ttl="3600">
<actions>
<download software="rr" />
</actions>
</dload>
```

| Атрибут | Переменная окружения | По умолчанию | Значение |
|-------------|----------------------|---------------------------|---------------------------------------------------------------------------------|
| `cache-dir` | `DLOAD_CACHE_DIR` | каталог кэша пользователя | Каталог реестра версий. |
| `cache-ttl` | `DLOAD_CACHE_TTL` | `600` | Сколько секунд действует последняя проверка репозитория. `0` отключает реестр. |

Переменная окружения имеет приоритет над атрибутом в `dload.xml`, а опция командной строки над обоими.

```bash
# Проверить репозитории на новые релизы, даже если последняя проверка ещё свежая
./vendor/bin/dload get rr --refresh

# Забыть репозитории, из которых берётся программа, или весь реестр целиком
./vendor/bin/dload cache:clear rr
./vendor/bin/dload cache:clear --force
```

> [!NOTE]
> В реестре хранятся только метаданные релизов: теги, имена и ссылки на ассеты. Загрузки через него
> не проходят, учётные данные в нём не сохраняются, поэтому каталог можно свободно передавать между
> машинами и складывать в кэш CI. Если проверка не удалась из-за сетевой ошибки или лимита API,
> используются сохранённые релизы, а репозиторий, который раньше не встречался, по-прежнему
> завершится ошибкой. Сохранённый релиз, ассеты которого исчезли из источника, удаляется из
> реестра сразу после неудачной загрузки, а список релизов запрашивается заново, прежде чем
> запуск завершится ошибкой.
> Черновики релизов GitHub никогда не выдаются; реестр хранит только их теги как скрытые заглушки, занимающие позицию в списке. Релиз, который провайдер вставляет не в начало списка, например релиз GitLab с задним числом в `released_at`, проверка не замечает; чтобы его подхватить, выполните `cache:clear` для этой программы.

В GitHub Actions каталог можно переносить между запусками workflow, тогда запуск тратит лимит API
только на релизы, вышедшие после предыдущего:

```yaml
- name: Restore DLoad version registry
uses: actions/cache@v4
with:
path: ./runtime/dload-cache
key: dload-registry-${{ github.run_id }}
restore-keys: dload-registry-

- run: ./vendor/bin/dload get
env:
DLOAD_CACHE_DIR: ./runtime/dload-cache
```

`github.run_id` в ключе заставляет каждый запуск сохранять свой реестр, а `restore-keys` позволяет
следующему запуску начать с самого свежего. Параллельные джобы одного workflow кэш друг друга не
видят: `actions/cache` сохраняет его по завершении джобы.

## Сборка кастомного RoadRunner

DLoad поддерживает сборку кастомных бинарников RoadRunner с помощью инструмента сборки Velox. Это полезно когда нужен RoadRunner с определёнными комбинациями плагинов, которые недоступны в готовых релизах.
Expand Down
64 changes: 64 additions & 0 deletions README-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ DLoad 解决了 PHP 项目中的一个实际问题:如何在分发 PHP 代码
- [下载类型](#下载类型)
- [版本约束](#版本约束)
- [高级配置选项](#高级配置选项)
- [版本注册表](#版本注册表)
- [构建自定义 RoadRunner](#构建自定义-roadrunner)
- [构建动作配置](#构建动作配置)
- [Velox 动作属性](#velox-动作属性)
Expand Down Expand Up @@ -172,6 +173,7 @@ composer require internal/dload -W
| `--stability` | 发布稳定性 (stable, beta) | stable |
| `--config` | 配置文件路径 | ./dload.xml |
| `--force`, `-f` | 即使二进制文件已存在也强制下载 | false |
| `--refresh`, `-r` | 即使版本注册表仍然有效,也检查仓库是否有新发布 | false |

### 查看软件

Expand Down Expand Up @@ -348,6 +350,68 @@ DLoad 支持三种下载类型,它们决定了资源的处理方式:
</dload>
```

### 版本注册表

解析版本意味着向 GitHub 或 GitLab 请求仓库的发布列表。DLoad 会把获取到的信息保存在本地的
**版本注册表**中:这是一个小型数据库,记录每个已知仓库的发布版本和资产,每个仓库一个 JSON 文件。
其中的版本永不过期,过期的只是仓库的*最近一次检查*:只要检查时间比 `cache-ttl` 更新,`dload get`
就直接从注册表返回结果,不会发出任何 API 请求。检查过期后,DLoad 只向 API 请求此后发布的版本,
通常只需一次请求。

发布页面仍然按需加载。首次运行只获取找到满足所需版本的发布所需的页面,更早的发布会在之后真正需要时再加载。

注册表默认启用,位于用户缓存目录(`$XDG_CACHE_HOME/dload`,Windows 下为 `%LOCALAPPDATA%\dload\cache`,
其他情况为 `~/.cache/dload`):

```xml
<dload temp-dir="./runtime" cache-dir="./runtime/dload-cache" cache-ttl="3600">
<actions>
<download software="rr" />
</actions>
</dload>
```

| 属性 | 环境变量 | 默认值 | 含义 |
|-------------|--------------------|--------------|----------------------------------------------|
| `cache-dir` | `DLOAD_CACHE_DIR` | 用户缓存目录 | 版本注册表所在目录。 |
| `cache-ttl` | `DLOAD_CACHE_TTL` | `600` | 最近一次检查保持有效的秒数。`0` 表示禁用注册表。 |

环境变量优先于 `dload.xml` 中的属性,命令行选项优先于两者。

```bash
# 即使最近一次检查仍然有效,也强制检查仓库是否有新发布
./vendor/bin/dload get rr --refresh

# 忘记某个软件所使用的仓库,或清空整个注册表
./vendor/bin/dload cache:clear rr
./vendor/bin/dload cache:clear --force
```

> [!NOTE]
> 注册表只保存发布的元数据:标签、名称和资产下载链接。下载不会经过注册表,也不会保存任何凭据,
> 因此该目录可以自由共享或放入 CI 缓存。若因网络错误或 API 速率限制导致检查失败,会使用已保存的发布;
> 从未见过的仓库仍会明确报错。若某个已保存发布的资产在上游已被删除,下载失败后它会立即从注册表中移除,
> 并在本次运行放弃之前重新获取发布列表。
> GitHub 的草稿发布永远不会被提供;注册表只以隐藏占位符的形式保存其标签,用于占据列表中的位置。若提供方将某个发布插入到列表开头以下的位置,例如 GitLab 中 `released_at` 被回填的发布,检查不会发现它;请对该软件运行 `cache:clear` 以获取它。

在 GitHub Actions 中可以在多次工作流运行之间保留该目录,这样每次运行只为上次运行之后发布的版本消耗速率限制:

```yaml
- name: Restore DLoad version registry
uses: actions/cache@v4
with:
path: ./runtime/dload-cache
key: dload-registry-${{ github.run_id }}
restore-keys: dload-registry-

- run: ./vendor/bin/dload get
env:
DLOAD_CACHE_DIR: ./runtime/dload-cache
```

键中的 `github.run_id` 使每次运行都保存自己的注册表,而 `restore-keys` 让下一次运行从最新的注册表开始。
同一工作流中并行运行的作业彼此看不到缓存,因为 `actions/cache` 在作业结束时才保存缓存。

## 构建自定义 RoadRunner

DLoad 支持使用 Velox 构建工具来构建自定义 RoadRunner 二进制文件。当你需要包含特定插件组合的 RoadRunner,而这些组合在预构建版本中不可用时,这功能就很有用了。
Expand Down
Loading
Loading