Skip to content

Commit 626b2e4

Browse files
committed
Update AGENTS and WARP
1 parent 286c3fe commit 626b2e4

File tree

2 files changed

+307
-1
lines changed

2 files changed

+307
-1
lines changed

AGENTS.md

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
# Guía de estilo y operaciones generales
2+
3+
Guía operativa y de estilo para trabajar con este repositorio usando agentes.
4+
5+
Precedencia de reglas
6+
- Las reglas se aplican en orden de precedencia creciente: las que aparecen más tarde prevalecen sobre las anteriores.
7+
- Las reglas de proyecto (asociadas a rutas concretas) tienen prioridad sobre reglas personales.
8+
- Entre reglas de proyecto, las de subdirectorios prevalecen sobre las del directorio padre.
9+
10+
## Comunicación y formato
11+
- Conversaciones y asistencia: en español.
12+
- Código, mensajes de commit, comentarios de código y resúmenes de PR: en inglés.
13+
- PR: usar texto sin escapar en asunto y cuerpo.
14+
15+
## Terminal y ejecución
16+
- No cerrar la terminal ni ejecutar comandos que finalicen la sesión.
17+
- Evitar comandos interactivos salvo que sea estrictamente necesario.
18+
- Extremar cuidado con comillas simples y dobles en los comandos.
19+
20+
## Despliegue y CI
21+
22+
- Se realiza mediante azure-pipelines.yml.
23+
- La build debe pasar correctamente antes de fusionar una PR.
24+
25+
## Lineamientos de diseño y estilo (C# / Reactive)
26+
27+
- Preferir programación funcional y reactiva cuando no complique en exceso.
28+
- Validación: preferir ReactiveUI.Validations.
29+
- Result handling: usar CSharpFunctionalExtensions cuando sea posible.
30+
- Convenciones:
31+
- No usar sufijo “Async” en métodos que devuelven Task.
32+
- No usar guiones bajos para campos privados.
33+
- Evitar eventos (salvo indicación explícita).
34+
- Favorecer inmutabilidad; mutar solo lo estrictamente necesario.
35+
- Evitar poner lógica en Observable.Subscribe; preferir encadenar operadores y proyecciones.
36+
37+
# Errores y notificaciones
38+
39+
- Para flujos de Result<T> usar el operador Successes.
40+
- Para fallos, HandleErrorsWith() empleando INotificationService para notificar al usuario.
41+
42+
# Toolkit Zafiro
43+
44+
Es mi propio toolkit. Disponible en https://github.com/SuperJMN/Zafiro. Muchos de los métodos que no conozcas pueden formar parte de este toolkit. Tenlo en consideración.
45+
46+
# Manejo de bytes (sin Streams imperativos)
47+
48+
- Usar Zafiro.DivineBytes para flujos de bytes evitables con Stream.
49+
- ByteSource es la abstracción observable y componible equivalente a un stream de lectura.
50+
51+
# Refactorización guiada por responsabilidades
52+
53+
1. Leer el código y describir primero sus responsabilidades.
54+
2. Enumerar cada responsabilidad como una frase nominal clara.
55+
3. Para cada responsabilidad, crear una clase o método con nombre específico y semántico.
56+
4. Extraer campos y dependencias según cada responsabilidad.
57+
5. Evitar variables compartidas entre responsabilidades; si aparecen, replantear los límites.
58+
6. No introducir patrones arbitrarios; mantener la interfaz pública estable.
59+
7. No eliminar logs ni validaciones existentes.
60+
61+
62+
# General guidelines about this repo
63+
64+
This file guides Warp (and future contributors) on how CI/CD and packaging work in this repository.
65+
66+
Scope: whole repository (DotnetPackaging).
67+
68+
CI pipeline (Azure Pipelines)
69+
- Definition: azure-pipelines.yml at repo root.
70+
- Agent: windows-latest.
71+
- Versioning: computed with GitVersion.Tool; packages use MajorMinorPatch as Version; GitHub Release tag uses v{SemVer}.
72+
- Behavior on master:
73+
- Restore, build and pack all projects; push .nupkg (non-symbol) to NuGet (skip-duplicate) with $(NuGetApiKey).
74+
- Publish Windows EXE stubs (DotnetPackaging.Exe.Installer) for win-x64 and win-arm64 as single-file self-extract apps (IncludeNativeLibrariesForSelfExtract/IncludeAllContentForSelfExtract, no trimming).
75+
- Produce .sha256 for each stub and upload both .exe and .sha256 to a GitHub Release tagged v{SemVer} using gh CLI.
76+
- Other branches/PRs: build and pack only (no push, no release).
77+
- Packable projects: every project with IsPackable/PackAsTool set. The CLI tool lives in src/DotnetPackaging.Tool (PackAsTool=true).
78+
79+
Versioning (GitVersion)
80+
- GitVersion.Tool runs in CI to produce:
81+
- Version: MajorMinorPatch (used for dotnet build/pack).
82+
- TagName: v{SemVer} (used to create/update the GitHub Release).
83+
- Practical effect: merging to master triggers package publish to NuGet and stub upload to a GitHub Release for the computed tag.
84+
85+
Secrets
86+
- The pipeline expects a variable group named api-keys providing:
87+
- NuGetApiKey: API key used to push packages to NuGet.
88+
- GitHubApiKey: token exposed as GITHUB_TOKEN to create/update releases and upload stub assets via gh.
89+
- Do not hardcode secrets. Locally, export environment variables and pass them to the CLI tools.
90+
91+
Local replication
92+
- Pack locally:
93+
- dotnet restore
94+
- dotnet build -c Release -p:ContinuousIntegrationBuild=true -p:Version=1.2.3 --no-restore
95+
- dotnet pack -c Release --no-build -p:IncludeSymbols=false -p:SymbolPackageFormat=snupkg -p:Version=1.2.3 -o ./artifacts/nuget
96+
- Push to NuGet:
97+
- For each .nupkg (non-symbol): dotnet nuget push ./artifacts/nuget/<pkg>.nupkg --api-key "$env:NUGET_API_KEY" --source https://api.nuget.org/v3/index.json --skip-duplicate
98+
- Build Windows stubs (on Windows):
99+
- dotnet publish src/DotnetPackaging.Exe.Installer/DotnetPackaging.Exe.Installer.csproj -c Release -r win-x64 -p:PublishSingleFile=true -p:SelfContained=true -p:IncludeNativeLibrariesForSelfExtract=true -p:IncludeAllContentForSelfExtract=true -p:PublishTrimmed=false -o ./artifacts/stubs/win-x64
100+
- Repeat for win-arm64 by changing -r.
101+
- Release (optional):
102+
- gh release create v1.2.3 --title "DotnetPackaging 1.2.3" --notes "Local release"
103+
- gh release upload v1.2.3 ./artifacts/stubs/win-*/DotnetPackaging.Exe.Installer*.exe ./artifacts/stubs/win-*/DotnetPackaging.Exe.Installer*.exe.sha256 -R <owner>/<repo>
104+
105+
Notes
106+
- Because the CLI is a dotnet tool (PackAsTool=true) and is included in the solution, CI will pack and publish it to NuGet alongside the libraries when running on master.
107+
- The pipeline performs a shallow fetch depth override (full history) to ensure GitVersion/describe work correctly.
108+
109+
Packaging formats: status and details
110+
- AppImage (Linux)
111+
- Status: supported and used. Library: src/DotnetPackaging.AppImage (net8.0).
112+
- How it works: builds an AppDir from a published app directory, generates AppRun, .desktop and AppStream files, discovers icons, then creates a SquashFS and concatenates the official AppImage runtime.
113+
- Runtime retrieval: downloads AppImageKit runtime per architecture (x86_64/armhf/aarch64) via RuntimeFactory. No external tools required (no linuxdeploy, no appimagetool).
114+
- Icon strategy: automatic discovery under the provided directory; if none, falls back to common names (icon.svg, icon-256.png, icon.png). Optionally writes .DirIcon.
115+
- Debugging: set DOTNETPACKAGING_DEBUG=1 to dump intermediate Runtime*.runtime and Image*-Container.sqfs in the temp folder.
116+
- Debian .deb (Linux)
117+
- Status: supported and used. Library: src/DotnetPackaging.Deb.
118+
- How it works: lays out files under /opt/<package>, generates .desktop under /usr/local/share/applications and a wrapper under /usr/local/bin/<package>.
119+
- Packaging: fully managed (no external dpkg-deb required). Icons are optionally embedded under hicolor/<size>/apps/<package>.png.
120+
- RPM .rpm (Linux)
121+
- Status: supported and used. Library: src/DotnetPackaging.Rpm; exposed via CLI.
122+
- How it works: stages files under /opt/<package>, writes a .desktop in /usr/share/applications and a wrapper in /usr/bin/<package>.
123+
- Packaging: uses system rpmbuild to assemble the package. Requires rpm-build to be installed locally.
124+
- Portability: auto-generated dependency/provides under /opt/<package> are excluded (using %global __requires_exclude_from/__provides_exclude_from), preventing hard Requires like liblttng-ust.so.0 and making self-contained .NET apps install across RPM-based distros.
125+
- Ownership: the package only owns directories under /opt/<package>; system directories (/usr, /usr/bin, etc.) are not owned to avoid conflicts with filesystem packages.
126+
- MSIX (Windows)
127+
- Status: experimental/preview. Library: src/DotnetPackaging.Msix with tests in src/DotnetPackaging.Msix.Tests.
128+
- CLI: exposed via msix pack (from directory) and msix from-project (publishes then packs). Assumes a valid AppxManifest.xml and assets are present; metadata generation can be added.
129+
- Validation: tests unpack resulting MSIX using makeappx tooling in CI-like conditions.
130+
- Flatpak (Linux)
131+
- Status: supported (bundle via system `flatpak`) with internal OSTree bundler fallback.
132+
- Libraries: src/DotnetPackaging.Flatpak (Factory, Packer, OSTree scaffolding).
133+
- How it works: builds a Flatpak layout (metadata at root, files/ subtree) from a publish directory; icons auto-detected and installed under files/share/icons/.../apps/<appId>.(svg/png). Desktop Icon is forced to <appId>.
134+
- Bundling: prefers system `flatpak build-export/build-bundle`; if not available or fails, uses internal bundler to emit a single-file `.flatpak` (unsigned, for testing).
135+
- Defaults: freedesktop runtime 24.08 (runtime/sdk), branch=stable, common permissions (network/ipc, wayland/x11/pulseaudio, dri, filesystem=home). Command defaults to AppId.
136+
- DMG .dmg (macOS)
137+
- Status: experimental cross-platform builder. Library: src/DotnetPackaging.Dmg.
138+
- How it works: emits an ISO9660/Joliet image (UDTO) with optional .app scaffolding if none exists. Special adornments like .VolumeIcon.icns and .background are hoisted to the image root when present.
139+
- Notes: intended for simple drag-and-drop installs. Not a full UDIF/UDZO implementation; signing and advanced Finder layouts are out of scope for now.
140+
- Windows EXE (.exe) — preview
141+
- Status: preview. Dotnet-only SFX builder. Library: src/DotnetPackaging.Exe. Stub Avalonia: src/DotnetPackaging.Exe.Installer (esqueleto WIP).
142+
- How it works: produces a self-extracting installer by concatenating [stub.exe][payload.zip][Int64 length]["DPACKEXE1"]. The payload contains metadata.json and Content/ (publish output). The stub leerá metadata y realizará la instalación.
143+
- CLI: exe (desde carpeta publish) y exe from-project (publica y empaqueta). Si omites --stub, el packer descargará automáticamente el stub que corresponda desde GitHub Releases; puedes pasar --stub para forzar uno concreto.
144+
- Cross-platform build: el empaquetado (concatenación) funciona desde cualquier SO. El stub se publica por RID (win-x64/win-arm64).
145+
- Defaults: self-contained=true al generar desde proyecto; en hosts no Windows, especifica --rid (win-x64/win-arm64) para elegir el stub/target correcto.
146+
147+
CLI tool (dotnet tool)
148+
- Project: src/DotnetPackaging.Tool (PackAsTool=true, ToolCommandName=dotnetpackaging).
149+
- Commands available:
150+
- appimage: create an AppImage from a directory (typically dotnet publish output). Autodetects executable + architecture; generates metadata and icons.
151+
- appimage from-project: publish a .NET project and build an AppImage.
152+
- deb: create a .deb from a directory (dotnet publish output). Detects executable; generates metadata, .desktop and wrapper.
153+
- deb from-project: publish a .NET project and build a .deb.
154+
- rpm: create an .rpm from a directory (dotnet publish output). Uses rpmbuild; excludes auto-deps under /opt/<package> and avoids owning system dirs.
155+
- rpm from-project: publish a .NET project and build an .rpm.
156+
- flatpak: layout, bundle (system or internal), repo, and pack (minimal UX).
157+
- flatpak from-project: publish a .NET project and build a .flatpak bundle.
158+
- msix (experimental): msix pack (from directory) and msix from-project.
159+
- dmg (experimental): dmg (from directory) and dmg from-project (publishes then builds a .dmg).
160+
- exe (preview): Windows self-extracting installer (.exe) from directory; and exe from-project (publica y empaqueta). Si omites --stub, se descargará el stub apropiado automáticamente.
161+
- Common options (all commands share a metadata set):
162+
- --directory <dir> (required): input directory to package from.
163+
- --output <file> (required): output file (.AppImage, .deb, .rpm, .msix, .flatpak, .dmg).
164+
- --application-name, --wm-class, --main-category, --additional-categories, --keywords, --comment, --version,
165+
--homepage, --license, --screenshot-urls, --summary, --appId, --executable-name, --is-terminal, --icon <path>.
166+
- Examples (from a published folder):
167+
- AppImage (dir): dotnetpackaging appimage --directory /path/to/publish --output /path/out/MyApp.AppImage --application-name "MyApp"
168+
- AppImage (project): dotnetpackaging appimage from-project --project /path/to/MyApp.csproj --output /path/out/MyApp.AppImage --application-name "MyApp"
169+
- Deb (dir): dotnetpackaging deb --directory /path/to/publish --output /path/out/myapp_1.0.0_amd64.deb --application-name "MyApp"
170+
- Deb (project): dotnetpackaging deb from-project --project /path/to/MyApp.csproj --output /path/out/myapp_1.0.0_amd64.deb --application-name "MyApp"
171+
- RPM (dir): dotnetpackaging rpm --directory /path/to/publish --output /path/out/myapp-1.0.0-1.x86_64.rpm --application-name "MyApp"
172+
- RPM (project): dotnetpackaging rpm from-project --project /path/to/MyApp.csproj --output /path/out/myapp-1.0.0-1.x86_64.rpm --application-name "MyApp"
173+
- Flatpak (minimal): dotnetpackaging flatpak pack --directory /path/to/publish --output-dir /path/out
174+
- Flatpak (bundle): dotnetpackaging flatpak bundle --directory /path/to/publish --output /path/out/MyApp.flatpak --system
175+
- Flatpak (project): dotnetpackaging flatpak from-project --project /path/to/MyApp.csproj --output /path/out/MyApp.flatpak --system
176+
- MSIX (dir, experimental): dotnetpackaging msix pack --directory /path/to/publish --output /path/out/MyApp.msix
177+
- MSIX (project, experimental): dotnetpackaging msix from-project --project /path/to/MyApp.csproj --output /path/out/MyApp.msix
178+
- DMG (dir, experimental): dotnetpackaging dmg --directory /path/to/publish --output /path/out/MyApp.dmg --application-name "MyApp"
179+
- DMG (project, experimental): dotnetpackaging dmg from-project --project /path/to/MyApp.csproj --output /path/out/MyApp.dmg --application-name "MyApp"
180+
- EXE (preview, dir): dotnetpackaging exe --directory /path/to/win-x64/publish --output /path/out/Setup.exe --rid win-x64 --application-name "MyApp" --appId com.example.myapp --version 1.0.0 --vendor "Vendor"
181+
- EXE (preview, project): dotnetpackaging exe from-project --project /path/to/MyApp.csproj --rid win-x64 --output /path/out/Setup.exe --application-name "MyApp" --appId com.example.myapp --version 1.0.0 --vendor "Vendor"
182+
183+
Tests
184+
- AppImage tests (test/DotnetPackaging.AppImage.Tests):
185+
- CreateAppImage validates building from containers and saving bytes.
186+
- SquashFS tests ensure filesystem construction integrity.
187+
- Deb tests (test/DotnetPackaging.Deb.Tests):
188+
- Integration tests covering metadata and tar entries layout.
189+
- MSIX tests (src/DotnetPackaging.Msix.Tests):
190+
- Validate building MSIX and unpacking with makeappx to assert structure.
191+
- EXE tests (test/DotnetPackaging.Exe.Tests):
192+
- Validate metadata zip creation and concatenation format; basic install path resolution.
193+
- Gaps / TODOs:
194+
- Add CLI end-to-end tests (invocation of dotnetpackaging appimage/deb/rpm/exe on temp publishes and validating outputs).
195+
- Integrate dotnet test into azure-pipelines.yml.
196+
- Improve EXE installer UI and add Windows E2E tests.
197+
198+
Developer workflow tips
199+
- Publish input
200+
- AppImage/Deb/RPM/Flatpak/MSIX consume a folder produced by dotnet publish. from-project subcommands invoke a minimal publisher and reuse the same pipelines.
201+
- For AppImage, ensure an ELF executable is present (self-contained single-file publish is acceptable). If not specified, the first eligible ELF is chosen.
202+
- RID/self-contained
203+
- from-project defaults:
204+
- rpm/deb/appimage: self-contained=true by default. RID is optional; if you need to cross-publish (target a different OS/arch than the host), pass --rid (e.g., linux-x64/linux-arm64).
205+
- msix: self-contained=false by default. RID is optional; pass --rid when cross-publishing (e.g., win-x64/win-arm64).
206+
- dmg: requires --rid (osx-x64 or osx-arm64). Host RID inference is intentionally not used to avoid producing non-mac binaries when running on Linux/Windows.
207+
- flatpak: framework-dependent by default; uses its own runtime. You can still publish self-contained by passing --self-contained and --rid if needed.
208+
- RPM prerequisites
209+
- Install rpmbuild tooling: dnf install -y rpm-build (or the equivalent on your distro).
210+
- The RPM builder excludes auto-deps/provides under /opt/<package> to keep self-contained .NET apps portable and avoid liblttng-ust.so.N issues across distros.
211+
- The package does not own system directories; only /opt/<package> and files explicitly installed (wrapper under /usr/bin and .desktop in /usr/share/applications).
212+
- Icon handling
213+
- The CLI and libraries attempt to discover icons automatically. You can override via --icon or supply common names in the root (icon.svg, icon-256.png, icon.png).
214+
- Debug
215+
- Set DOTNETPACKAGING_DEBUG=1 to dump AppImage intermediate artifacts (runtime + squashfs).
216+
217+
Repository map (relevant)
218+
- src/DotnetPackaging.AppImage: AppImage core (AppImageFactory, RuntimeFactory, SquashFS).
219+
- src/DotnetPackaging.Deb: Debian packaging (Tar entries, DebFile).
220+
- src/DotnetPackaging.Rpm: RPM packaging (layout builder and rpmbuild spec generation).
221+
- src/DotnetPackaging.Msix: MSIX packaging (builder and helpers).
222+
- src/DotnetPackaging.Exe: Windows SFX packer (concatenation and metadata).
223+
- src/DotnetPackaging.Exe.Installer: Avalonia stub installer.
224+
- src/DotnetPackaging.Tool: CLI (dotnet tool) with commands appimage, deb, rpm, flatpak, msix, exe.
225+
- test/*: AppImage and Deb tests; src/DotnetPackaging.Msix.Tests for MSIX; test/DotnetPackaging.Exe.Tests for EXE packaging.
226+
227+
Backlog / Future work
228+
- Add CLI E2E tests (including rpm/exe) and hook dotnet test in CI.
229+
- Optional: enrich icon detection strategies and metadata mapping (e.g., auto-appId from name + reverse DNS).
230+
231+
Windows EXE (.exe) – progress log (snapshot)
232+
- Done:
233+
- Librería DotnetPackaging.Exe con SimpleExePacker (concatena stub + zip + footer).
234+
- Comandos CLI: exe (desde carpeta) y exe from-project (publica y empaqueta). --stub es opcional; si se omite, el packer descarga el stub que corresponda desde GitHub Releases.
235+
- Stub Avalonia creado (esqueleto) en src/DotnetPackaging.Exe.Installer con lector de payload.
236+
- Instalador: opción de crear acceso directo en Escritorio en el paso Finish; acceso directo en Start Menu se mantiene.
237+
- CI: publica stubs win-x64 y win-arm64 como single-file self-extract con hashes y los sube a un GitHub Release (tag v{SemVer}).
238+
- Packer: logging antes de descargar el stub para informar del tiempo de espera.
239+
- Next:
240+
- UI: Integrar SlimWizard de Zafiro en el stub (ahora hay UI mínima). Navegación con WizardNavigator y páginas.
241+
- Lógica: Elevación UAC y carpeta por defecto en Program Files según arquitectura.
242+
- Packer: caché local de stubs y reintentos/validación de hashes.
243+
- Detección avanzada de ejecutable e icono (paridad con .deb/.appimage).
244+
- Modo silencioso.
245+
- Pruebas E2E en Windows.

0 commit comments

Comments
 (0)