Use `--pd-modal-fade` CSS variable for the cancel setup overlay
background instead of the hard-coded `bg-black` Tailwind color, so
the overlay respects the active theme (dark/light).
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
* fix(ui): stop carousel wheel swipes from navigating history
Prevent horizontal wheel events handled by the carousel from bubbling.
Add UI and renderer regression tests for the propagation boundary.
Fixes#16531
AI-assisted: GitHub Copilot
Signed-off-by: Zhey-on <anpropagate@aol.com>
* test(renderer): harden nested wheel navigation regression
Add a positive control to prove the global wheel handler is active before\nasserting nested stopped wheel events do not trigger history navigation.\nReset cooldown and mocks between phases to avoid false positives.
AI-assisted: GitHub Copilot
Signed-off-by: Zhey-on <anpropagate@aol.com>
---------
Signed-off-by: Zhey-on <anpropagate@aol.com>
the function would wrongfully return false if there was no podman
binary which caused a premature error for onboarding when hyperv
was the only provider
Signed-off-by: Brian <bmahabir@bu.edu>
Signed-off-by: Simon Rey <srey@redhat.com>
Co-authored-by: Simon Rey (via Cursor AI) <srey@redhat.com>
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Signed-off-by: Simon Rey <srey@redhat.com>
Co-authored-by: Simon Rey (via Cursor AI) <srey@redhat.com>
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Address review feedback: drop "Podman Desktop" from the version check
failure message and remove duplicated predicate in downloadCommand
when-clause.
Signed-off-by: Simon Rey <simon.rey@outlook.com>
Co-authored-by: Claude <claude@anthropic.com>
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
When the GitHub API rate limit is hit (or any network error occurs),
checkDownloadedCommand now catches the failure, sets a
composeVersionCheckFailed context value, and the onboarding flow
displays a dedicated error step instead of proceeding with broken
placeholder text.
Fixes#13868
Signed-off-by: Simon Rey <simon.rey@outlook.com>
Co-authored-by: Claude <claude@anthropic.com>
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Made-with: Cursor
* feat(storybook): auto-regenerate themes.css on color-registry changes
Add a Vite plugin that watches `color-registry.ts` and
`tailwind-color-palette.json`, then re-runs `storybook:css` and
triggers a full reload.
Also pass explicit svelte config path and watch UI package dist for
changes.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
* fix(storybook): queue file changes during in-flight theme regeneration
Previously, saves that arrived while storybook:css was already
running were silently dropped. Now a queued flag is set and a
second regeneration runs after the first completes, so
back-to-back edits are never lost.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
* fix(storybook): use node: prefix for Node.js built-in imports
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
---------
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Rey <srey@redhat.com>
Co-authored-by: Simon Rey (via Cursor AI) <srey@redhat.com>
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Add a comprehensive skill at .agents/skills/new-extension/SKILL.md that
guides agents through creating standalone external extensions with:
- Multi-package layout (backend + Svelte frontend + optional shared)
- TypeScript Vite configs (vite.config.ts) with defineConfig
- Svelte 5 with runes syntax and svelte.config.js for preprocessing
- Backend/frontend tsconfig.json with correct targets (Node vs DOM)
- Backend-to-frontend messaging via postMessage
- Containerfile for OCI image packaging
- Build, test, and publish workflows
- Quick reference table for common API patterns
🤖 Generated with AI assistance
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Made-with: Cursor
* chore: update electron app name to be from product.json and use correct logs files paths
Signed-off-by: Sonia Sandler <ssandler@redhat.com>
* chore: update copyrights years
Signed-off-by: Sonia Sandler <ssandler@redhat.com>
#### What does this PR do?
Updates the node-forge package overide to 1.4.0 (new release:
https://www.npmjs.com/package/node-forge)
Affected function: retrieveWindowsCertificates()
#### Screenshot / video of UI
N/A
#### What issues does this PR fix or reference?
CVE fixes / security alerts.
#### How to test this PR?
Verify that certificate handling with Windows machines works as normal when pulling /
pushing an image behind CA on your host.
Verify "refreshing catalog" works fine / can download extensions
Verify PD on Windows starts up / no errors in console regarding certificate issues.
Signed-off-by: Charlie Drage charlie@charliedrage.com
Signed-off-by: Charlie Drage charlie@charliedrage.com
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
When a provider (e.g. Kind) reports updateInfo but the CLI is not
actually installed, the Resources page would show an Update button that
hangs indefinitely when clicked.
Root cause: the Kind extension registers a provider update even when
kindPath is undefined (CLI not installed). Additionally, the renderer
only compared versions without checking that the provider has a version
at all.
Fixes:
- Kind extension: skip provider.registerUpdate when kindPath is not set
- Renderer: require provider.version to exist before showing the button
- ProviderUpdateButton: add the same guard as defense-in-depth
Closes#13639
Signed-off-by: Simon Rey <music.music.music@hotmail.com>
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Revert the biome ignore for schemas/ and instead run biome format
as the final step of generate:schemas so the committed output
matches what CI produces.
Signed-off-by: Simon Rey <simon@podman-desktop.io>
AI-assisted: yes
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Generated JSON schemas use JSON.stringify output and should not
be reformatted by biome, avoiding CI drift between generation
and formatting passes.
Signed-off-by: Simon Rey <simon@podman-desktop.io>
AI-assisted: yes
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Signed-off-by: Simon Rey <simon@podman-desktop.io>
AI-assisted: yes
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Terms in SearchTermParser were unconditionally lowercased, which caused
the search term to lose its casing when changeScreen stripped filter
tokens and reassigned it — making FilteredEmptyScreen display
"No extensions matching 'a' found" instead of "'A'".
Parser responsibilities separated: terms now retain their original
casing; filter values are still lowercased at parse time since they are
only used for case-insensitive comparison. filterCatalogExtensions is
updated to lowercase terms at comparison time.
AI-assisted
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Extract timeout logic into a shared withTimeout utility
Closes#16701
Co-Authored-By: Claude (glm-5.1)
Signed-off-by: sheikhlimon <sheikhlimon404@gmail.com>
This fix resolves conflict between podman-desktop protocol handlers registered by upstream and downstream projects when installed together for the same user. Each downstream project should maintain unique protocol name across all downstream projects.
Signed-off-by: Denis Golovin <dgolovin@redhat.com>
* fix(renderer): deduplicate aria-labels in troubleshooting components
Three troubleshooting components had the same aria-label value on two
sibling DOM elements that co-exist simultaneously, making them
indistinguishable for screen readers.
- TroubleshootingRepair: remove redundant aria-label from inner heading
div; the outer role="region" already carries the "Repair" label and
the visible text is self-labeling
- TroubleshootingContainerEngines: rename role="status" label from
"Container Connections" to "Container connections count" to
distinguish it from the enclosing region
- TroubleshootingPageStores: rename role="list" label from "stores" to
"stores list" to distinguish it from the role="status" heading
Spec files updated to match the new labels.
Fixes#17021
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
* test(renderer): fix aria-label selector in troubleshooting tests
Update getByRole queries to use 'Container connections count'
instead of 'Container Connections', matching the aria-label
added to the role="status" element in TroubleshootingContainerEngines.
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
---------
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(ui): redesign button component with shared color tokens
Rework Button.svelte to use semantic color tokens (primary-border,
secondary-bg, secondary-border, disabled-bg, focus-ring, link-bg, etc.)
instead of hardcoded palette references. Add prerequisite color
dependency validation in initButton, deprecate legacy color aliases
(button-secondary, button-disabled, button-danger-hover-text), and
improve accessibility with aria-disabled, aria-busy, and
focus-visible outlines.
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
* chore: update documentation links to be used from product.json
Signed-off-by: Sonia Sandler <ssandler@redhat.com>
* chore: adjust types in product.json
Signed-off-by: Sonia Sandler <ssandler@redhat.com>
Replace `text-[var(--pd-progressBar-text)]` with the Tailwind v4
parenthesis shorthand `text-(--pd-progressBar-text)` in both the
component and its test assertion.
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
Add missing aria-label to the bulk delete button in
`TaskManagerBulkDeleteButton` (reusing the title prop) and to the
`add-build-argument` button in `BuildImageFromContainerfile`.
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
Replace hardcoded Tailwind `text-purple-500` with
`text-[var(--pd-progressBar-text)]` to use the color-registry CSS
variable.
Add test coverage for the component's class names and color token usage.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
Add aria-label attributes to the five pairs of add/delete link
buttons (volume mounts, env variables, security options, DNS
servers, extra hosts) to satisfy the icon-only button requirement.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
Add unit tests for provider.registerUpdate registration, no-op when
already on latest, and provider update callback wiring. Mock CliTool
version from createCliTool options so update availability matches runtime.
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Register provider.update when a CLI update is available so the
Resources page matches CLI Tools (same pattern as Kind).
Related to #13640
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Add unit tests for provider.registerUpdate registration, no-op when
already on latest, and provider update callback wiring. Mock CliTool
version from createCliTool options so update availability matches runtime.
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Register provider.update when a CLI update is available so the
Resources page matches CLI Tools (same pattern as Kind).
Create the provider before onboarding commands so onboarding can pass
provider into registerCLITool.
Related to #13640
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* refactor(e2e): remove flaky build log validation and simplify WSL skip
Drop validateBuildLogs from buildImage — xterm scrollback limits made the
assertion unreliable on CI. Skip the entire Complex Containerfile describe
block upfront on WSL instead of catching failures mid-run with skipTests flag.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Anton Misskii <amisskii@redhat.com>
* refactor(e2e): restore terminal visibility assertion after build log removal
Re-add a minimal toBeVisible() check on the xterm terminal after the
Done button becomes enabled. This confirms the terminal rendered during
the build without the fragile content inspection that was removed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Anton Misskii <amisskii@redhat.com>
* chore(e2e): clarify WSL skip reason for complex manifest build
Explain why the complex Containerfile fails on WSL (RUN steps require
foreign-arch binary execution without QEMU) while the simple one
succeeds (only CMD metadata, no execution during build).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Anton Misskii <amisskii@redhat.com>
* fix(e2e): wrap test.skip condition in arrow function to defer evaluation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Anton Misskii <amisskii@redhat.com>
---------
Signed-off-by: Anton Misskii <amisskii@redhat.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
MSW v2.13.0 added `network` and `#private` properties to the
`SetupServerApi` class, making it incompatible with the return type of
`setupServer()` which is the `SetupServer` interface.
Replace `SetupServerApi` with `SetupServer` in all test files so the
Dependabot PR for msw >=2.13.0 can land without typecheck failures.
Signed-off-by: Sal Rey <srey@redhat.com>
AI-assisted: Claude
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* feat(e2e): adding chrome dev tools protocol runner
Signed-off-by: axel7083 <42176370+axel7083@users.noreply.github.com>
* chore(test): adjust cdp runner to accommodate test runner design from electron runner
Signed-off-by: Ondrej Dockal <odockal@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
---------
Signed-off-by: Ondrej Dockal <odockal@redhat.com>
Signed-off-by: axel7083 <42176370+axel7083@users.noreply.github.com>
Co-authored-by: axel7083 <42176370+axel7083@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
- Add network smoke tests covering full container lifecycle:
- Check default network exists
- Create network and verify it exists
- Pull image for container test
- Start container using user-defined network (fix navigation: after
startContainer() with alpine /bin/sh the app lands on Container
Details → Tty tab, not Containers list; use navigationBar.openContainers()
explicitly)
- Verify container inspect shows correct network (use Monaco Find
widget via Ctrl+F instead of tabContent.toContainText() which only
checks the visible viewport of the virtualized editor)
- Stop and delete the network container
- Delete network from networks page
- Delete network from details page
- Add searchInEditor(tabName, text) to DetailsPage base class for
reusable Monaco editor search across all detail pages
- Add searchInInspectEditor(text) convenience wrapper in ContainerDetailsPage
- Add selectUserDefinedNetwork(networkName) to RunImagePage
Signed-off-by: Anton Misskii <amisskii@redhat.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
The openExternal command was calling Electron's shell.openExternal()
directly, bypassing the security restriction handler that validates
URLs and prompts the user before opening unknown domains.
The fix routes it through securityRestrictionCurrentHandler instead,
consistent with how env.openExternal() in the extension API already works.
Signed-off-by: Denis Golovin <dgolovin@users.noreply.github.com>
Co-authored-by: axel7083 <42176370+axel7083@users.noreply.github.com>
Today, labeler is added but as the GitHub app is adding labels
to approve/review domains, there is like a loop effect
where when user is approving, bot is adding the label then
it starts again the PR checks...
only drawback is that if you add the `area/ci` label it means
you need to push a change to the branch to trigger it
Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
it's done by the GitHub app that is adding the domains now
Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
When autoStart is true, the machine start command now runs in detached
mode, allowing the process to continue independently even if Podman
Desktop exits.
AI assisted
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* feat(color-registry): add default-text-link and default-item-hover tokens
Add shared default color tokens for link/tab accent
(`default-text-link`) and subtle hover overlay (`default-item-hover`)
with HC theme support.
Move `initCommon()` before `initButton()` in init order, so
`item-disabled` is available when button colors are registered.
Add HC values to `item-disabled`.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
* test(color-registry): align default token tests with updated values
Update `default-text-link` test to match adjusted light/hcLight
palette steps. Add HC alpha assertions for `default-item-hover`.
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
* fix(color-registry): use resetAllMocks in beforeEach per project convention
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
---------
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
Co-authored-by: Claude <noreply@anthropic.com>
I had the choices with
> this result could not be resolved under your current 'moduleResolution' setting
>. Consider updating to 'node16', 'nodenext', or 'bundler'.
using node16 or nodenext would result in many .js imports suffix missing in
the src/ folder. I picked up then bundler to have the smallest changes
Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
OKLCH-interpolate light (50-400) and dark (800-950) steps so
chroma stays proportional to lightness. The previous ramp
skewed toward gray, making lighter UI elements appear washed
out. Core brand values (500, 600, 700) are unchanged.
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
Co-authored-by: Claude <noreply@anthropic.com>
Prepare `Exec.exec` for upcoming async file operations by marking the
method `async`. No functional change — the return type is already
`Promise<RunResult>`.
Signed-off-by: Sakamoto Rei <srey@users.noreply.github.com>
🤖 AI assisted
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Made-with: Cursor
* fix: refine high contrast theme color definitions
Remove redundant hcDark defaults, add missing hcLight values, and replace
purple accent colors with accent1 palette for consistency across all UI
components. Improves accessibility and visual consistency in HC themes.
This commit refines the high contrast theme support by:
- Removing redundant color definitions that matched defaults
- Adding comprehensive hcLight theme support
- Standardizing on the accent1 color palette instead of purple
- Using semantic black/white values for better contrast
- Improving readability with consistent formatting
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
* fix: add high contrast overrides for text and icon color tokens
Ensure text, header, and icon tokens use pure white (hcDark) and
pure black (hcLight) in high contrast themes for maximum
readability. Also fix tab-text hcLight from charcoal[900] to black
for consistency, and add missing hcDark to details-empty-cmdline-text.
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
* fix(color-registry): add missing hcDark overrides for text and background color tokens
Several color tokens had hcLight defined but were missing the
corresponding hcDark value, causing them to fall back to the
dark theme color rather than the intended high contrast dark value.
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
* test(color-registry): update tooltip color assertions to include hcDark and hcLight values
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
* fix(color-registry): correct hcDark value for global nav icon-selected token
Was set to black, which would be invisible against a dark HC background.
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
* refactor(color-registry): extract titlebar and card prefix constants
Replaces hardcoded string literals in initTitlebar and initCardContent
with local prefix variables, consistent with the pattern used elsewhere
in the registry.
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
* fix(color-registry): add hcDark and hcLight overrides for dropdown item hover background
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
---------
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
* chore(test): enchance port forwarding e2e test to cover miltiple pods/services configuration
Signed-off-by: Dias Tursynbayev <original.justmello1337@gmail.com>
* chore: setup eslint no-sync rule and document all sync FS usages
- Added eslint-plugin-n and configured n/no-sync rule as a warning
- This enables tracking of synchronous FS API usages across the codebase
- No code refactoring yet; warnings serve as documentation for migration planning
Signed-off-by: SACHIN KUMAR <mrmister680@gmail.com>
* chore(test): include specific AGENTS.md doc under tests/playwright sub project
Signed-off-by: Ondrej Dockal <odockal@redhat.com>
Co-authored-by: Code Claude <noreply@anthropic.com>
Add @media (prefers-reduced-motion: reduce) CSS rule to disable the
spinner animation when users prefer reduced motion.
Resolves#15806
Signed-off-by: Simon Rey <simontestmail@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
.claude/skills should be a symlink to .agents/skills
here it's making .claude/.agents/skills
Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
Replaces the custom animate-spin border trick with the official
Spinner component from @podman-desktop/ui-svelte for consistency
with the refreshed spinner design.
Resolves#16240
Signed-off-by: Simon Rey <simontestmail@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Made-with: Cursor
When fixing another issue in esm imports for inversify
I faced a 'undefined' error
I guess the logic was to use || or !(a && b)
Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
SMIL animations (animateTransform) cannot be controlled by CSS media
queries such as @media (prefers-reduced-motion: reduce). This makes it
impossible to respect user motion accessibility preferences via CSS.
Replace the SMIL animation with an equivalent CSS @keyframes animation
using steps(8) discrete rotation at 720ms — visually identical behavior
— so that future CSS-based accessibility rules can control it.
Signed-off-by: Simon Rey <simontestmail@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
chore(test): add advanced nagivation history e2e test spec
Signed-off-by: Ondrej Dockal <odockal@redhat.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Use role attribute to find the warning component, because aria-label
is removed from Warning component.
Signed-off-by: Priyansh Sao <saopriyansh06@gmail.com>
Use role attribute to find the warning component, because aria-label
is removed from Warning component.
Signed-off-by: Priyansh Sao <saopriyansh06@gmail.com>
Removes the hardcoded aria-label which stops screen readers from reading
the actual warning message.
Signed-off-by: Priyansh Sao <saopriyansh06@gmail.com>
Inversify 8 no longer accepts arbitrary values as service identifiers:
only strings, symbols, or class constructors.
This replaces the Promise.withResolvers<BrowserWindow> function reference
with a proper Symbol.for('MainWindowDeferred') token.
related to https://github.com/podman-desktop/podman-desktop/issues/16631
Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Florent <fbenoit@redhat.com>
On Windows with HiDPI scaling (e.g. 200% at 5K resolution), the tray
icon appeared pixelated because nativeImage.addRepresentation() does not
work reliably on Windows for registering scale factor variants.
Fix by loading the @2x PNG directly via createFromBuffer with explicit
width/height at logical 1x size, giving Windows the full 32px of pixel
data to render a sharp 16pt icon at 200% scaling.
Signed-off-by: Alyn <alynrtiedtke@gmail.com>
* chore(test): add navigation smoke e2e test spec and requirements doc.
Signed-off-by: Ondrej Dockal <odockal@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
* chore(test): add managed configuration tests for proxy settings
Signed-off-by: Tibor Dancs (work-laptop) <tdancs@redhat.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Moved HMR configuration from vite plugin's 'hot' option to compilerOptions.hmr
in svelte.config.js as required by Svelte 5, which has HMR integrated in core.
This fixes the warning: "[vite-plugin-svelte] svelte 5 has hmr integrated in
core. Please remove the vitePlugin.hot option and use compilerOptions.hmr instead"
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Signed-off-by: Fred Bricon <fbricon@gmail.com>
* feat: handle high contrast themes in appearance init and isDark store
Signed-off-by: Vladyslav Zhukovskyi <vzhukovs@redhat.com>
* feat: handle high contrast themes in appearance init and isDark store
Signed-off-by: Vladyslav Zhukovskyi <vzhukovs@redhat.com>
---------
Signed-off-by: Vladyslav Zhukovskyi <vzhukovs@redhat.com>
The `@types/tar` package is deprecated as `tar` now ships its own
type definitions. Remove it from `packages/main/package.json` and
update the lockfile.
Closes#16716
Signed-off-by: Baixiaochun <182930459+Bingtagui404@users.noreply.github.com>
The enhanced dashboard feature is not yet ready — enabling the toggle
results in an empty dashboard. Mark the configuration as hidden so it
does not appear in the Experimental Features page until the dashboard
content is implemented.
Signed-off-by: Sebastien Rey <srey@redhat.com>
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
The ExperimentalPage filtered properties only by `!!property.experimental`
but did not check `property.hidden`, unlike PreferencesRendering and
PreferencesResourcesRendering. This meant setting `hidden: true` on an
experimental configuration had no effect on the Experimental Features page.
Signed-off-by: Sebastien Rey <srey@redhat.com>
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Generate a JSON Schema from the Zod ExtensionManifestSchema using
z.toJSONSchema(), composed with the SchemaStore package.json schema
via allOf for standard field validation.
Signed-off-by: AI Assistant <noreply@podman-desktop.io>
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
feat(certificates): add command to palette to sync sertificates to podman VMs
this commit adds:
1. synchronization of local certificates to all running local podman machines
2. synchronization is incremental and based on fingerprinting
3. if multiple machines are running sychronization will run in separate
tasks visible in Task Manager view
4. if synchronization fails for one machine other tasks let to finish
5. user can call synchronization using command from the palette
Signed-off-by: Denis Golovin <dgolovin@redhat.com>
* chore: added api for enhanced dashboard
Signed-off-by: Evzen Gasta <evzen.ml@seznam.cz>
* chore: renamed status to health monitor status
Signed-off-by: Evzen Gasta <evzen.ml@seznam.cz>
---------
Signed-off-by: Evzen Gasta <evzen.ml@seznam.cz>
* chore(test): refactor settings constants into modular structure
Split monolithic settings.ts into separate files for better organization:
- preferences.ts: all preference-related constants
- registries.ts: all registry-related constants
Export both classes directly from main index.ts.
Update imports to use direct per-class imports.
Co-authored-by: Code Claude <noreply@anthropic.com>
Signed-off-by: Tibor Dancs (work-laptop) <tdancs@redhat.com>
* chore(test): add support for detecting managed registries configuration
Add isPreferredManaged() method to RegistriesPage to detect if the
"Preferred Repositories" field is marked as managed by enterprise configuration.
The method uses scoped locators to find the "Managed" label within the specific
preference section and handles timeout errors gracefully using the codebase
pattern of checking error.name === "TimeoutError" rather than instanceof.
Co-authored-by: Code Claude <noreply@anthropic.com>
Signed-off-by: Tibor Dancs (work-laptop) <tdancs@redhat.com>
* chore(test): add registries configuration to managed-configuration test resources
Add registry-related managed configuration settings:
- Default preferred repositories: docker.io, quay.io
- Default registries configuration with docker.io and quay.io entries
- Lock registries.preferred field to prevent user modifications
Co-authored-by: Code Claude <noreply@anthropic.com>
Signed-off-by: Tibor Dancs (work-laptop) <tdancs@redhat.com>
* chore(test): add managed configuration tests for registries
Add comprehensive E2E tests for managed registries configuration:
- Verify preferred repositories field shows managed configuration value
- Check field is readonly when locked (not disabled)
- Validate registries.conf file is created with correct TOML structure
- Use polling to wait for file creation (avoid CI race conditions)
- Parse TOML robustly with dynamic regex matching (order-independent)
Co-authored-by: Code Claude <noreply@anthropic.com>
Signed-off-by: Tibor Dancs (work-laptop) <tdancs@redhat.com>
* chore(test): use tag-based filtering for managed-configuration tests
Replace file-specific test targeting with tag-based filtering using
@managed-configuration tag. This allows running all managed configuration
tests regardless of which spec file they are in, providing better test
organization and execution flexibility.
Co-authored-by: Code Claude <noreply@anthropic.com>
Signed-off-by: Tibor Dancs (work-laptop) <tdancs@redhat.com>
* chore(test): code review fixes
Signed-off-by: Tibor Dancs (work-laptop) <tdancs@redhat.com>
---------
Signed-off-by: Tibor Dancs (work-laptop) <tdancs@redhat.com>
Co-authored-by: Code Claude <noreply@anthropic.com>
Hide the blue container and related text on the welcome page when there
are no onboarding providers, preventing an empty blue rectangle from
appearing during initial onboarding.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Signed-off-by: Fred Bricon <fbricon@gmail.com>
### What does this PR do?
Adds a setting to disable the extension catalog throughout PD.
This can be done by adding the setting manually to your
`~/.local/share/containers/podman-desktop/configuration/settings.json`
with:
```
"extensions.catalog.enabled": false
```
Which will disable the appearance of the catalog throughout PD.
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
Closes https://github.com/podman-desktop/podman-desktop/issues/16036
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
- [X] Tests are covering the bug fix or the new feature
1. Edit
`~/.local/share/containers/podman-desktop/configuration/settings.json`
2. Add: `"extensions.catalog.enabled": false`
3. Start / Restart PD
4. See that you cannot access the catalog from the following places:
Extensions, Settings > Authentication, and Kubernetes (with no
context).
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Add ability to cancel in-progress image pull operations with new Cancel button.
Includes backend support for cancellable tokens and proper error handling for
cancelled operations.
Signed-off-by: Dias Tursynbayev <original.justmello1337@gmail.com>
Update Pull image button to show dynamic text and be disabled during pull operation.
Signed-off-by: Dias Tursynbayev <original.justmello1337@gmail.com>
### What does this PR do?
Adds a setting when set in
`~/.local/share/containers/podman-desktop/configuration/settings.json`
disables showing the "Local Extensions" tab.
### Screenshot / video of UI
`extensions.localExtensions.enabled": true`:
`extensions.localExtensions.enabled": false`:
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
Closes https://github.com/podman-desktop/podman-desktop/issues/16037
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
- [X] Tests are covering the bug fix or the new feature
1. Edit `~/.local/share/containers/podman-desktop/configuration/settings.json`
2. Set `extensions.localExtensions.enabled": false`
3. `pnpm watch`
4. See there no more "Local Extensions" tab in Extensions section
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
there are several new versions, for each major versions
ensure each version of minimatch should use the latest .z release
from the major release
fixes https://github.com/advisories/GHSA-3ppc-4f35-3m26
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
Subscribe to the registered features store and listen for
onDidChangeRegisteredFeatures events so the Kubernetes navigation
entry is dynamically hidden when an extension declares the
"kubernetes-contexts-manager" feature.
Closes#16528
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
ExperimentalConfigurationManager now depends on Telemetry, so it must
be registered in the DI container after Telemetry is bound and
initialized.
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Track an `experimentalConfigurationUpdate` event with the config key
and whether the feature is being enabled or disabled whenever
`updateExperimentalConfigurationValue` is called.
Closes#16471
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
prior to trying to update eslint itself
@eslint/compat from 2.0.2 to 2.0.3
@eslint/eslintrc from 3.3.3 to 3.3.5
eslint-plugin-svelte from 3.15.0 to 3.15.1
related to https://github.com/podman-desktop/podman-desktop/issues/16131
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
Use `updateExperimentalConfigurationValue` for records with the
`experimental` property set, falling back to `updateConfigurationValue`
for standard records. Add tests covering both paths.
Made-with: Cursor
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* feat(renderer): add new buttons to PullImage page
Signed-off-by: Dias Tursynbayev <original.justmello1337@gmail.com>
* chore(test): edit e2e to fit new button name
Signed-off-by: Dias Tursynbayev <original.justmello1337@gmail.com>
* refactor(renderer): add GitHubFeedbackCategory type
Signed-off-by: Dias Tursynbayev <original.justmello1337@gmail.com>
* fix(renderer): save previously typed title and decription in GitHubFeedback
Replace two conditions by one so the Feedback form component is the same instance and avoid duplicates. This prevents the typed text from being erased when the user switches categories.
Signed-off-by: Dias Tursynbayev <original.justmello1337@gmail.com>
---------
Signed-off-by: Dias Tursynbayev <original.justmello1337@gmail.com>
### What does this PR do?
Moves the Prune, Load, Import and Pull buttons to be secondary and the
Create button to be a primary button.
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
Before:
After:
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
Closes https://github.com/podman-desktop/podman-desktop/issues/16357
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
Go see the buttons on the image page
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
### What does this PR do?
Moves the Prune & Gather volume sizes buttons to use the "secondary"
style now as the Create button is considered the "primary" button of
that section.
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
Before:
<img width="2274" height="1570" alt="image" src="https://github.com/user-attachments/assets/b87c565f-ce5e-478c-83a1-339be4a26fb0" />
After:
<img width="2274" height="1570" alt="image" src="https://github.com/user-attachments/assets/858c025e-2343-4cec-b652-4a5528fca4ea" />
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
Closes https://github.com/podman-desktop/podman-desktop/issues/16358
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
Go see the buttons on the volume page :)
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
* chore(api-sender): introduce type checking on channels
define the object type that is provided/received on a channel name
it'll allow to remove some custom casting when receiving the data
as the type is ensured from the definition of the channel
fixes https://github.com/podman-desktop/podman-desktop/issues/15632
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
Extract jsonEvent.status and jsonEvent.id into local const variables
to reduce repeated property access and prepare for upcoming Docker API
v1.52+ event format support.
No functional change.
Signed-off-by: Gerwin Bisschop <g.bisschop@iwink.nl>
* chore(imports): remove (or ignore) relative imports in main package
some JSON are imported using relative paths. As it is a more
per-case usage, ignore the rule for these one
For all others usecases, replace relative imports by path aliases
related to https://github.com/podman-desktop/podman-desktop/issues/14361
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
* chore(format): apply format
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
* chore: keep relative import for color-registry
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
---------
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
Add `Environment` combo to Containers, Pods, Images, Volumes and Network
pages to allow filter table content for specific provider connection.
Signed-off-by: Denis Golovin <dgolovin@redhat.com>
* refactor(SlideToggle): migrate to Svelte 5
Signed-off-by: Dias Tursynbayev <original.justmello1337@gmail.com>
* chore(SlideToggle): edit ariaInvalid and ariaLabel to be consistent with Dropdown
Signed-off-by: Dias Tursynbayev <original.justmello1337@gmail.com>
Reverts PR #16186 and PR #16104, which introduced visual issues. This
restores the stable color appearance from before the Tailwind 4
migration.
Fixes#16246
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
I saw a failure on this test, applying the same fix I did for another
details spec file that was failing a couple of days ago
related to https://github.com/podman-desktop/podman-desktop/pull/16213
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
now that these packages are using @podman-desktop/core-api import
remove the alias
related to #15496
there are still 2 preload packages to fix
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
and use prototype.
it avoids also to use .. by using import as well
but using import was leading issues to partial mocking
related to https://github.com/podman-desktop/podman-desktop/issues/14361
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
docs(release-docs): add note regarding cherry picking branch
### What does this PR do?
Adds a small note that you must fix create the branch by specifying the
tag in the step, before continuing.
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
N/A
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
N/A, found during release process.
### How to test this PR?
N/A
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
### What does this PR do?
Very small nitpick.. we don't capitalize for labels and noticed this
small one.
Should be "Image to pull" vs "Image to Pull".
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
N/A
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
`pnpm watch`
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
renderer was importing LogType definition from preload package
main was declaring a duplicated LogType at two places
now, reuse the one from api as well
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
I don't know if I'm the only one but as electron is no longer a dependency
it looks like my renderer part typecheck is failing due to the usage
of Electron import
remove this usage and do like it's done in WebView.svelte
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
instead of using typescript alias `/@api` use the new
`@podman-desktop/core-api` dependency
related to #15496
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
* chore(main): import api using package rather than alias
instead of using typescript alias `/@api` use the new
`@podman-desktop/core-api` dependency
related to #15496
---------
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
package.json was referencing entries that were not at
the expected location.
Update vite configuration to generate it as expected
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
* chore(deps): update electron-builder from v26.0.12 to v26.7.0
- remove the patch we had to fix background on macOS v26
- add the non @2x background else the window size is broken
(before there was a bug being fixed now)
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
* chore: handle universal binaries
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
* chore(builder): replace @1x DMG background (#5)
Signed-off-by: Václav Vančura <vancura@users.noreply.github.com>
---------
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
Signed-off-by: Václav Vančura <vancura@users.noreply.github.com>
Co-authored-by: Václav Vančura <vancura@users.noreply.github.com>
adds fixup on the rules from this plug-in
it adds compatibility rules to make it compliant
with v10 eslint version
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
on PR check, argos ci is failing almost all the time
it's about the mermaid diagram that has different rendering
the diagram was already excluded in the css but it looks like
that it was not excluded in fact, adding new entry in the css
fixes https://github.com/podman-desktop/podman-desktop/issues/15875
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
there is a describe method in the middle of tests. It's probably
related to an issue of a rebase.
Just move the inner describe method to the root level
newer vitest versions failed to run these tests
related to https://github.com/podman-desktop/podman-desktop/pull/16182
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
some files were added into api package without exports
thus it was failing when wanting to import them
through package import (not typescript aliases)
related #15496
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
introduce dedicated package.json files for each package in the
packages/ folder that don't have one
it'll make possible to add dependencies to core-api or other modules
related to #15496https://github.com/podman-desktop/podman-desktop/issues/15677
note: follow-up will be required to remove dependencies from the
root package.json
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
* refactor: update networks routes to be nested
Signed-off-by: Sonia Sandler <ssandler@redhat.com>
* fix: after rebase
Signed-off-by: Sonia Sandler <ssandler@redhat.com>
for now only extensions had their version being updated
it'll avoid to see in source code 0.0.0 or 0.1.0 versions for packages/*/package.json
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
* feat(color-registry): update colors to Tailwind 4
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
* fix(color-registry): restore the gray-25 color token
The gray-25 was removed in Tailwind 4, resulting in failing tests.
There are no other colors that need restoring.
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
* test(color-registry): update tests to use OKLCH color values
Update color-registry.spec.ts to reference tailwindColorPalette values
instead of hardcoded hex colors. This aligns the tests with the updated
color palette that now uses OKLCH format for gray and purple shades.
Fixed 3 failing assertions:
- titlebar-bg light color (Windows and macOS/Linux tests)
- titlebar-text light color (extension theme test)
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
---------
Signed-off-by: Vaclav Vancura <commit@vancura.dev>
Signed-off-by: Dias Tursynbayev <dtursynb@dtursynb-thinkpadt14gen6.tpb.csb>
Co-authored-by: Dias Tursynbayev <dtursynb@dtursynb-thinkpadt14gen6.tpb.csb>
* refactor: updateImage to latest build backend
update image feature will be orchestrated by the ui.
updatable function was created in image registry
Assited-by: Cursor
Signed-off-by: Brian <bmahabir@bu.edu>
* fix: address docker false positive update available
for multi arch images on docker it only stores the manifest
list unlike podman which stores both. This made for a list to platform
check that wasnt correct leading to the false positives. Now I also
return the list digest when available for comparison
Signed-off-by: Brian <bmahabir@bu.edu>
---------
Signed-off-by: Brian <bmahabir@bu.edu>
fix(nsis): use dynamic product name for Windows registry cleanup
### What does this PR do?
Replaces hardcoded "Podman Desktop" string with `${PRODUCT_NAME}` variable
in the NSIS uninstaller script for registry key deletion.
### Why is this needed?
The auto-start registry entry is created by Electron using the productName
from the build config:
```typescript
// windows-startup.ts:86-90
app.setLoginItemSettings({
openAtLogin: true,
path: `"${this.podmanDesktopBinaryPath}"`,
args,
});
```
The productName comes from:
```javascript
// .electron-builder.config.cjs:109
productName: product.name,
```
```json
// product.json:3
"name": "Podman Desktop",
```
electron-builder automatically defines `PRODUCT_NAME` for NSIS scripts
already (https://github.com/electron-userland/electron-builder/blob/master/packages/app-builder-lib/src/targets/nsis/NsisTarget.ts#L210):
```nsis
// installer.nsh:4-5
DeleteRegValue HKCU "...\Run" "${PRODUCT_NAME}"
DeleteRegValue HKCU "...\StartupApproved\Run" "${PRODUCT_NAME}"
```
### How to test this PR?
1. Build and install Podman Desktop on Windows
2. Enable "Start on login" in preferences
3. Uninstall the application
4. Verify registry keys are removed from:
- `HKCU\Software\Microsoft\Windows\CurrentVersion\Run`
- `HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run`
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
when a new directory is created fs.watcher emits an
unintended error. We should filter only by .cdix extension
files to avoid this
Signed-off-by: Brian <bmahabir@bu.edu>
* refactor(mock): generate @podman-desktop/api mock from its definition
instead of writing for each function and for each namespace the content
reuse the .d.ts definition and wire automatically vi.fn()
customize/override some classes implementation manually but most of it is generated
fixes https://github.com/podman-desktop/podman-desktop/issues/14493
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
* feat(certificats-ui): view only Certificates Preference page
Introduce certificate svelte store with certificate information
relevant for UI. A certificate in store has subject, issuer, serial
number and expiration extracted from RDNs.
Introduce Certificates Preference page that shows the certificates from
svelte store as a Table with 4 columns:
1. Subject
2. Issuer
3. Serial #
4. Expiration date
The Preference page allows you to:
1. see Subject common name if CN RDN is available or full Subject string
2. see Issuer common name or 'Self signed'
2. see Serial # as it is in certificate
4. see Expiration date icon
5. change sorting on individual columns
6. search in the table by Certificate or Issuer name
Signed-off-by: Denis Golovin <dgolovin@redhat.com>
---------
Signed-off-by: Denis Golovin <dgolovin@redhat.com>
### What does this PR do?
Fixes the Chocolatey package update script that was failing with:
```
au_GetLatest failed
Object reference not set to an instance of an object.
```
The script was scraping the GitHub page, which recently broke. This switches to the GitHub API.
### Screenshot / video of UI
N/A
### What issues does this PR fix or reference?
Closes https://github.com/podman-desktop/podman-desktop/issues/15896
### How to test this PR?
```powershell
# Install au if not already
choco install au -y
# Run script
cd .chocolatey/podman-desktop
$env:VERSION = "1.25.0"
./update.ps1
# Expect nuspec & releaseNotes to be updated
```
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
Fix links to Code of Conduct - point both to our CoC (which in turn points to CNCF CoC).
Remove invalid .md from CODEOWNERS.
Signed-off-by: Tim deBoer <git@tdeboer.ca>
We're overdue adopting a governance policy. Full credit for this content goes to @slemeur,
I've just done the final markdown cleanup and PR creation.
Signed-off-by: Tim deBoer <git@tdeboer.ca>
Our security policy was still pointing to the policy in the containers org and needs
to be updated. (e.g. disclosure should not be via the Podman security list)
We have one public mailing list today that anyone can join,
cncf-podman-desktop-maintainers@lists.cncf.io. We've created a second, private list
for security issues: cncf-podman-desktop-security@lists.cncf.io.
This PR keeps the same policy/process as the containers org, except:
- asks for disclosure via our own -security list
- adds GitHub security reporting as another option
- announcements are done via our own -maintainers. (announcements could go elsewhere
later, but it doesn't seem worth creating another list at this point)
Fixes#15762.
Signed-off-by: Tim deBoer <git@tdeboer.ca>
* feat: stop/start internal kubernetes monitoring
Signed-off-by: Philippe Martin <phmartin@redhat.com>
* feat: show/hide kubernetes icon
Signed-off-by: Philippe Martin <phmartin@redhat.com>
* test: update tests
Signed-off-by: Philippe Martin <phmartin@redhat.com>
* test: add unit tests
Signed-off-by: Philippe Martin <phmartin@redhat.com>
* fix: type
Signed-off-by: Philippe Martin <phmartin@redhat.com>
* fix: prevent stop/start several times
Signed-off-by: Philippe Martin <phmartin@redhat.com>
* chore: update telemetry link and add privacy link to feedback form
Bending the rules a little with 1 PR to resolve 2 related issues as they touch 2
of the same files.
We have had feedback from RH legal on two things:
- #15862: The telemetry infoLink is not a _privacy_ statement and shouldn't be
called one. The proposed change is from 'Read our privacy statement' to 'For
more information read our statement'.
- #15861: The feedback form offers to collect your email address, so it should
link to a separate url that is a privacy statement.
This change:
- Updates the infoLink to the proposed text.
- Adds a privacyLink and privacyURL to product.json.
- Adds the new privacy link to the feedback form (identical to telemetry link
in WelcomePage).
Used onMount instead of $derived in FeedbackForm because I do not want to trigger
Svelte 5 migration as part of this issue.
Fixes#15862.
Fixes#15861.
Signed-off-by: Tim deBoer <git@tdeboer.ca>
* chore: change telemetry info and privacy to objects
We had infoLink/infoURL and privacyLink/privacyURL. This changes them both to be
simple objects with link/url properties.
There is a bunch of change, but overall it is slightly simpler and better
structured since info and privacy are still optional, but once you provide them
the properties aren't.
Signed-off-by: Tim deBoer <git@tdeboer.ca>
---------
Signed-off-by: Tim deBoer <git@tdeboer.ca>
* feat(authentication): implement extension allowance and session access control
- Added methods to read/update allowed extensions for authentication providers
- Implemented a check for access permissions for extensions
- Updated tests to cover new functionality
Signed-off-by: Denis Golovin <dgolovin@redhat.com>
* fix: extension created the session should be allowed to use it
Fix modifies the getSession so it adds requesting extension to
the allowance list as allowed to use the created session.
Signed-off-by: Denis Golovin <dgolovin@redhat.com>
* refactor(authentication): update allowance keying
- Changed the allowance key format to use account ID instead of account
name for better uniqueness.
- Updated related methods and tests to reflect this change, ensuring
consistent access control for extensions.
- Enhanced fallback mechanism to display account ID when the label is not
available.
Signed-off-by: [Your Name] <your.email@example.com>
Signed-off-by: Denis Golovin <dgolovin@redhat.com>
---------
Signed-off-by: Denis Golovin <dgolovin@redhat.com>
Signed-off-by: [Your Name] <your.email@example.com>
The extension catalog currently exposes all extensions from getExtensions(). The
only users of this are the extension updater (which filters out incompatible
extensions) and the renderer extension catalog (which currently didn't, and allows
you to install them).
This moves the filtering of incompatible extensions from the updater directly into
the catalog getExtensions(). This simplifies the updater and fixes the issue in
the renderer.
Tests updated. It felt odd to remove the test from the updater at first, but this
case can never happen and the same test is now directly in the catalog.
(replaces draft PR attempt #15769 that filtered in the renderer)
Fixes#15767.
Signed-off-by: Tim deBoer <git@tdeboer.ca>
Add comprehensive size variants and real-world usage examples, plus Storybook theme-aware fallback tokens to keep labels readable in light/dark previews.
Co-authored-by: Claude <noreply@anthropic.com>
* feat: set Kubernetes experimental as simple preference
Signed-off-by: Philippe Martin <phmartin@redhat.com>
* feat: isExperimentalConfigurationEnabled supports boolean
Signed-off-by: Philippe Martin <phmartin@redhat.com>
* feat: remove video for kubernetes experimental feature
Signed-off-by: Philippe Martin <phmartin@redhat.com>
### What does this PR do?
On flatpak, the traditional `/usr/share/` directory is not accessible,
and rather it's accessible via `/run/host/usr/share` from within the flatpak.
This is accessible by adding: ` - "--filesystem=host-os:ro"` to our
flatpak yaml, which gives read-only support for the host file system
with the ability to access the /usr/share/podman-desktop directory via
`/run/host/usr/share/podman-desktop`.
This change allows us to detect if we are running in a flatpak
environment and change where we are finding our managed configuration
file anyways.
We use `process.env.FLATPAK_ID` throughout Podman Desktop anyways :)
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
Closes https://github.com/podman-desktop/podman-desktop/issues/15314
### How to test this PR?
1. Create file `/usr/share/podman-desktop/default-settings.json`:
```sh
{ "telemetry.enabled": false }
```
and
`/usr/share/podman-desktop/locked.json`:
```sh
{ "locked": ["telemetry.enabled"] }
```
2. Download the Flatpak manifest.
**SPECIAL NOTE:**
- This includes the upcoming changes to node24
- This pulls from this active branch the podman desktop build
- We pre-build podman desktop to get the artifacts / cache / enable
network access to that we can test this build
- Has the new parameter added (`host-os:ro`)
```
curl -O 135596fa62/io.podman_desktop.PodmanDesktop.yml
```
3. Build:
```
flatpak-builder --force-clean --disable-rofiles-fuse --user \
--install-deps-from=flathub --repo=repo builddir \
io.podman_desktop.PodmanDesktop.yml
```
4. Install:
```
flatpak --user install repo io.podman_desktop.PodmanDesktop
```
5. Start podman desktop, go to Settings > Telemetry, see that it is not
locked. You can also check your logs and see at the very top how it
is now loading default-settings.json and locked.json from
`/run/host`.
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
* feat: register features declared by extensions
Signed-off-by: Philippe Martin <phmartin@redhat.com>
* fix: typo
Signed-off-by: Philippe Martin <phmartin@redhat.com>
* feat: add FeatureRegistry to inversify container
Signed-off-by: Philippe Martin <phmartin@redhat.com>
* feat: added product name from product json in onboarding component
Signed-off-by: Marcel Bertagnini <mbertagn@redhat.com>
* fix: added unit test for product name in onboardin
Signed-off-by: Marcel Bertagnini <mbertagn@redhat.com>
* fix: added welcome message in onboarding info
Signed-off-by: Marcel Bertagnini <mbertagn@redhat.com>
* fix: added the replacecontextkeyplaceholders for display
Signed-off-by: Marcel Bertagnini <mbertagn@redhat.com>
---------
Signed-off-by: Marcel Bertagnini <mbertagn@redhat.com>
use IContext which is the interface rather than Context which is
the implementation class
it'll help to move context-info to the api package if only interface
is used
related to https://github.com/podman-desktop/podman-desktop/issues/14361
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
mocks are already done, no need to redefine them
prior to changes on removing the import of ../../../main
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
### What does this PR do?
Noticed a few incorrect things on the settings page:
* update to use preferences.appearance instead of appearance.apperance
* window.bounds is now the correct reference
* updated example so it is now correct
* reordered the settings page reference to be alphabetical
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
N/A, see website preview :)
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
Closes https://github.com/podman-desktop/podman-desktop/issues/15619
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
N/A
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
### What does this PR do?
Do not show the "reset to default" button when a preference item is
locked, since it's... locked anyways and you are unable to change it.
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
Closes https://github.com/podman-desktop/podman-desktop/issues/15305
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
- [X] Tests are covering the bug fix or the new feature
1. Setup your managed configuration with the following values:
```sh
~ $ cat /Library/Application\ Support/io.podman_desktop.PodmanDesktop/default-settings.json
{
"telemetry.enabled": "false"
}
~ $ cat /Library/Application\ Support/io.podman_desktop.PodmanDesktop/locked.json
{
"locked": ["telemetry.enabled"]
}
~ $
```
2. Go to Preferences.
3. See that the "reset" icon / button does not appear anymore for locked
a locked value.
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
* fix: add advanced feature tab to network create
Assited-by: Cursor opus
Signed-off-by: Brian <bmahabir@bu.edu>
* fix: reworked driveroptions and dns
now driveroptions is derived by instead of using the effect rune.
I now use onchange to reset network driver to bridge after a provider
change. Dnsenabled and server is undefined by default only set if
podman is a provider. If both podman and docker are found and podman
is set first then the values of dnsenabled and dnsserver will stay
set if switching to docker as docker doesnt use it anyways. Its more
for code clarity. Use libpod api for podman specific dns rather than
dockerode api
Signed-off-by: Brian <bmahabir@bu.edu>
* fix: added aria labels and defensive action for subnet req
Signed-off-by: Brian <bmahabir@bu.edu>
---------
Signed-off-by: Brian <bmahabir@bu.edu>
### What does this PR do?
Disables the SliderItem input when `record.locked` is true,
preventing edits to preferences / settings.
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
Part of https://github.com/podman-desktop/podman-desktop/issues/15306
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
1. Setup your managed configuration with the following values:
```sh
~ $ cat /Library/Application\ Support/io.podman_desktop.PodmanDesktop/default-settings.json
{
"preferences.zoomLevel": 0
}
~ $ cat /Library/Application\ Support/io.podman_desktop.PodmanDesktop/locked.json
{
"locked": ["preferences.zoomLevel"]
}
~ $
```
2. Try to move the zoom level slider
3. Unable to slide / it's disabled
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
### What does this PR do?
Disables the NumberItem input when `record.locked` is true,
preventing edits to preferences / settings.
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
Part of https://github.com/podman-desktop/podman-desktop/issues/15306
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
1. Setup your managed configuration with the following values:
```sh
~ $ cat /Library/Application\ Support/io.podman_desktop.PodmanDesktop/default-settings.json
{
"editor.fontSize": 14
}
~ $ cat /Library/Application\ Support/io.podman_desktop.PodmanDesktop/locked.json
{
"locked": ["editor.fontSize"]
}
~ $
```
2. Try to edit the editor font size input field
3. Unable to type / it's disabled
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
### What does this PR do?
Disables the StringItem input when `record.locked` is true,
preventing edits to preferences / settings.
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
Part of https://github.com/podman-desktop/podman-desktop/issues/15306
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
1. Setup your managed configuration with the following values:
```sh
~ $ cat /Library/Application\ Support/io.podman_desktop.PodmanDesktop/default-settings.json
{
"proxy.http": "http://proxy.example.com:8080"
}
~ $ cat /Library/Application\ Support/io.podman_desktop.PodmanDesktop/locked.json
{
"locked": ["proxy.http"]
}
~ $
```
2. Try to edit the HTTP proxy input field
3. Unable to type / it's disabled
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
### What does this PR do?
Disables the BooleanItem input when `record.locked` is true,
preventing edits to preferences / settings.
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
Part of https://github.com/podman-desktop/podman-desktop/issues/15306
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
1. Setup your managed configuration with the following values:
```sh
~ $ cat /Library/Application\ Support/io.podman_desktop.PodmanDesktop/default-settings.json
{
"telemetry.enabled": "false"
}
~ $ cat /Library/Application\ Support/io.podman_desktop.PodmanDesktop/locked.json
{
"locked": ["telemetry.enabled"]
}
~ $
```
2. Try to click on telemetry
3. Unable to click / it's disabled
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
### What does this PR do?
Disables the EnumItem dropdown when `record.locked` is true,
preventing edits to preferences / settings.
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
Part of https://github.com/podman-desktop/podman-desktop/issues/15306
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
1. Setup your managed configuration with the following values:
```sh
~ $ cat /Library/Application\ Support/io.podman_desktop.PodmanDesktop/default-settings.json
{
"preferences.appearance": "dark"
}
~ $ cat /Library/Application\ Support/io.podman_desktop.PodmanDesktop/locked.json
{
"locked": ["preferences.appearance"]
}
~ $
```
2. Try to change the appearance dropdown selection
3. Unable to select / it's disabled
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
### What does this PR do?
Disables the FileItem input when `record.locked` is true,
preventing edits to preferences / settings.
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
Part of https://github.com/podman-desktop/podman-desktop/issues/15306
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
1. Setup your managed configuration with the following values:
```sh
~ $ cat /Library/Application\ Support/io.podman_desktop.PodmanDesktop/default-settings.json
{
"kubernetes.Kubeconfig": "~/.kube/config"
}
~ $ cat /Library/Application\ Support/io.podman_desktop.PodmanDesktop/locked.json
{
"locked": ["kubernetes.Kubeconfig"]
}
~ $
```
2. Try to change the file path
3. Unable to browse / it's disabled
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
Adds telemetry messages to product.json and exposes them to the renderer package
using the same pattern as #15536. The acceptMessage is required, product.json
could omit the info link/url).
Uses the same message in both the Welcome page and telemetry preferences. This means
there is a slight visual change in what's clickable in the preferences. (From
"Read our [privacy statement]" to "[Read our privacy statement]", which matches the
Welcome page)
If there's no link or url, the link is omitted from both the preferences and
Welcome (issue #15379).
To test, remove welcome.version and telemetry.check from settings.json (being
careful not to break json formatting) so that you can see the Welcome page again.
Fixes#15350.
Fixes#15379.
Signed-off-by: Tim deBoer <git@tdeboer.ca>
chore(preferences input): if disabled, placeholder should should be disable font
### What does this PR do?
When an input is disabled, the placeholder text now uses the disabled
text colour instead of the regular colour.
This makes it easier to distinguish that it is in fact.. a component
that cannot add any input.
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
Before:
After:
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
Closes https://github.com/podman-desktop/podman-desktop/issues/15573
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
1. Go to Proxy page
2. Press System
3. See that the placeholder text is the same colour across all three
(HTTPS / HTTP + input on bottom)
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
### What does this PR do?
Like our Preference page / other parts of Podman Desktop, we should not
be "disabling" the titles, only the input sections.
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
Closes https://github.com/podman-desktop/podman-desktop/issues/15571
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
1. Go to Proxy Page
2. Press System
3. See that the titles no longer gray out
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
* fix: protect args passed to asascript
Signed-off-by: Philippe Martin <phmartin@redhat.com>
* test: fix unit test
Signed-off-by: Philippe Martin <phmartin@redhat.com>
* feat: also support antislash and quotes in args
Signed-off-by: Philippe Martin <phmartin@redhat.com>
* fix: copyright
Signed-off-by: Philippe Martin <phmartin@redhat.com>
* feat(product/help-menu): add help menu items to product definition
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* test: apply suggestion
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* refactor: apply @fbenoit requested change
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
---------
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
### What does this PR do?
In this PR we are adding visual indicators of when we are using locked
values for the following values:
```
"proxy.no": "localhost",
"proxy.http": "http://foobar.com",
"proxy.https": "https://foobar.com",
"proxy.enabled": 1
```
When we have these in `locked.json`:
```
{
"locked": ["telemetry.enabled", "proxy.https", "proxy.http", "proxy.no"]
}
```
They will then show in the UI that they are managed by your
organization.
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
Closes https://github.com/podman-desktop/podman-desktop/issues/15206
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
1. Setup your managed configuration with the following values:
```
~ $ cat /Library/Application\ Support/io.podman_desktop.PodmanDesktop/default-settings.json
{
"proxy.no": "localhost",
"proxy.http": "http://foobar.com",
"proxy.https": "https://foobar.com",
"proxy.enabled": 2
}
~ $ cat /Library/Application\ Support/io.podman_desktop.PodmanDesktop/locked.json
{
"locked": ["proxy.no", "proxy.https", "proxy.http", "proxy.enabled"]
}
~ $
```
2. Start PD
3. Go to **Preferences > Proxy**
4. See that the values are now disabled as well as the Managed
configuration indicators showing.
- [X] Tests are covering the bug fix or the new feature
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
* fix: move provider version to provider
Currently the provider version is shown as connection version,
which is misleading. That needs to come from each connection.
Better to show the provider version with the provider name,
and the connection version with the connection name (later)?
Signed-off-by: Anders F Björklund <anders.f.bjorklund@gmail.com>
### What does this PR do?
When record.readonly is true, the text input is now disabled,
preventing user interaction with the float number input field.
### Screenshot / video of UI
N/A, no (current) user facing change as it's more of a chore / align
with how other preferences such as BooleanItem does it with disabled /
readonly.
### What issues does this PR fix or reference?
Part of https://github.com/podman-desktop/podman-desktop/issues/14624
### How to test this PR?
- [X] Tests are covering the bug fix or the new feature
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
### What does this PR do?
When record.readonly is true, the Dropdown is now disabled,
preventing user interaction with the dropdown selection.
### Screenshot / video of UI
N/A, no (current) user facing change as it's more of a chore / align
with how other preferences such as BooleanItem does it with disabled /
readonly.
### What issues does this PR fix or reference?
Part of https://github.com/podman-desktop/podman-desktop/issues/14624
### How to test this PR?
- [X] Tests are covering the bug fix or the new feature
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
### What does this PR do?
When record.readonly is true, the range slider input is now disabled,
preventing user interaction with the slider.
### Screenshot / video of UI
N/A, no (current) user facing change as it's more of a chore / align
with how other preferences such as BooleanItem does it with disabled /
readonly.
### What issues does this PR fix or reference?
Part of https://github.com/podman-desktop/podman-desktop/issues/14624
### How to test this PR?
- [X] Tests are covering the bug fix or the new feature
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
### What does this PR do?
When record.readonly is true, the NumberInput is now disabled, preventing user interaction with the input field and increment/decrement buttons.
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
N/A, no (current) user facing change as it's more of a chore / align
with how other preferences such as BooleanItem does it with disabled /
readonly.
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
Part of https://github.com/podman-desktop/podman-desktop/issues/14624
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
- [X] Tests are covering the bug fix or the new feature
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
I haven't tracked down the direct cause, but at some point last year the path to
display string icons changed to using the i (italic) HTML component. This is
completely fine for FontAwesome icons, but for icons loaded from other sources like
product contributions it made them italicized.
This switches to use span instead. It's three extra characters :), but it is more
technically correct and we are already using it in other places (e.g. status bar).
We still use i to display icons in 20 other places (15 files), but I've verified
that these are all FontAwesome.
Fixes#15217. (and https://github.com/podman-desktop/extension-bootc/issues/2196)
Signed-off-by: Tim deBoer <git@tdeboer.ca>
### What does this PR do?
Noticed a few minor things!
* Should be "Create a"
* Buttons typically aren't titled (So should be `Play custom YAML`
instead of `Play Custom YAML`)
* Updates terminology when excuting / building a bit better
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
N/A, found when reviewing
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
- [X] Tests are covering the bug fix or the new feature
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
### What does this PR do?
When testing a compiled binary on macOS, it is a special case as there
is validation against the Electron binary before launching.
If you are using `pnpm compile:current`, you should be able to run the
app after launch.
Unfortunatley this requires:
```sh
codesign --force --deep --sign - "dist/mac-arm64/Podman Desktop.app"
```
To be ran.
This adds those instructions to the documentation.
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
N/A
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
N/A
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
1. Be on macOS
2. `pnpm compile:current`
3. Try to launch the binary (`dist/mac-arm64/Podman Desktop.app`)
4. Get error. Close app.
5. `codesign --force --deep --sign - "dist/mac-arm64/Podman
Desktop.app"`
6. No more error when launching.
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
before the backend used engineid, like get info, but for network create
we dont have access to this and must use providercontainerconnection instead
Signed-off-by: Brian <bmahabir@bu.edu>
* feat(renderer/help-menu): get items from backend for experimental
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* test: fix
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
---------
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* feat(main/help-menu): expose a method to get the items (empty for now)
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* fix: apply suggestion
Co-authored-by: axel7083 <42176370+axel7083@users.noreply.github.com>
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
---------
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Co-authored-by: axel7083 <42176370+axel7083@users.noreply.github.com>
fix(renderer/help-menu): provide names of font awesome icons to make it work with JSON
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* feat(ui): allow FontAwesome brands in Icon component
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* test: add UT
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
---------
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* feat(renderer): create empty experimental productized help menu
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* refactor: remove duplicated mock
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
---------
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* refactor(renderer): pass items for HelpActions component as a prop
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore: copyright date
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore: use describe
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* refactor(renderer): restore HelpActions name
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore: use describe
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* refactor: rename Generic to Items
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* fix: test was badly named
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore: update copyright
Co-authored-by: axel7083 <42176370+axel7083@users.noreply.github.com>
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* test: add missing items
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
---------
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Co-authored-by: axel7083 <42176370+axel7083@users.noreply.github.com>
Ensure the Node.js version available is matching the requirement of the build
I noticed that during the test of the PR
related to https://github.com/podman-desktop/podman-desktop/pull/15119
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
### What does this PR do?
While implementing
https://github.com/podman-desktop/podman-desktop/issues/15206 I noticed
numerous issues with the form vs the other parts of PD.
I looked at our other form pages (create container, build container) as
well as Preferences and applied some UI changes which follow our design
pattern and makes
https://github.com/podman-desktop/podman-desktop/issues/15206 easier to
implement.
These are UI/UX changes only and should NOT affect any form submissions,
etc.
- Make dropdown span full width instead of being constrained (it was
oddly small)
- Use consistent spacing between form groups (space-y-4). Before it was
wayyyyy to close together.
- Align label styling with other preferences pages (block + font-semibold)
- Fix incorrect "for" attribute on noProxy label (was applied in
https://github.com/podman-desktop/podman-desktop/pull/15378 but may
as well do it here..)
- Remove trailing colons from labels for consistency (we don't use this
anywhere else...)
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
Closes https://github.com/podman-desktop/podman-desktop/issues/15390
Part of https://github.com/podman-desktop/podman-desktop/issues/15206
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
Only visual changes, go to Proxy Settings page and see the difference
(or the above screenshots!)
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
* feat(main/help-menu): new experimental option for working on help menu
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore: update copyright
Co-authored-by: Philippe Martin <feloy1@gmail.com>
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore: update copyright
Co-authored-by: Philippe Martin <feloy1@gmail.com>
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore: update ticks
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore: update ticks
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore: remove unused
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
---------
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Co-authored-by: Philippe Martin <feloy1@gmail.com>
I noticed the telemetry text on the Welcome page and preferences have diverged slightly.
They should be the same, especially if we may allow it to be customized in the future
(should be one string).
I could have copy/pasted in either direction, but instead I used the best parts of both,
and confirmed with others that this is the most natural and readable version.
Related to #15379.
Signed-off-by: Tim deBoer <git@tdeboer.ca>
* fix(website): update release notes with PM comments
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* fix(website): grammar
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
---------
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
default was to take package.json name
also suffix by arch.
it'll require updates on the website for 1.25.0+
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
* chore(release): release notes 1.24
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore(release): clarify environment
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore: remove duplicate
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore: fix alt text
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore(website): apply suggestions
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore(website): add a hightlight for default registries
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore: add intro
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore: case
Co-authored-by: Matt Demyttenaere <matdemy@gmail.com>
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore: case
Co-authored-by: Matt Demyttenaere <matdemy@gmail.com>
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore: case
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore: add release banner
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore: trigger Build
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
* chore(website): apply @cdrage suggestion
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
---------
Signed-off-by: Simon Rey <51708585+simonrey1@users.noreply.github.com>
Co-authored-by: Matt Demyttenaere <matdemy@gmail.com>
* fix: rework updateimage error handling
Image already latest version was an error it should be
a success
Signed-off-by: Brian <bmahabir@bu.edu>
* fix: reworked update image catch error to be type safe
Signed-off-by: Brian <bmahabir@bu.edu>
---------
Signed-off-by: Brian <bmahabir@bu.edu>
by default electron-builder is using the package.json name and not config.appName
but only on Linux (not macOS or Windows...)
so at the end if we change some values in product.json it's not the one being applied
leading to an error while we try to call an unexisting file
fixes https://github.com/podman-desktop/podman-desktop/issues/15326
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
### What does this PR do?
It is: `~/.local/share/containers/podman-desktop/configuration/settings.json` on Linux / same as macOS.
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
N/A
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
N/A, caught this while clicking the tabs between the two!
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
N/A, minor doc change
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
* chore(test): pre-defining resource files for managed configuration tests
Signed-off-by: Tibor Dancs <tdancs@redhat.com>
* chore(test): adding basic smoke test for settings.json preferences
Signed-off-by: Tibor Dancs <tdancs@redhat.com>
* chore(tests): updated PR based on review
Signed-off-by: Tibor Dancs <tdancs@redhat.com>
* chore(test): switching to better locators
Signed-off-by: Tibor Dancs <tdancs@redhat.com>
* chore(test): coderabbit - expose Appearance label from preferences-page
Signed-off-by: Tibor Dancs <tdancs@redhat.com>
---------
Signed-off-by: Tibor Dancs <tdancs@redhat.com>
* fix: network create now routes to network summary
Assited-by: cursor opus
Signed-off-by: Brian <bmahabir@bu.edu>
* chore: fixed nav import and network store func
we dont need to check for name since podman
and docker could have the same name instead
we can check just for engineid and networkid
Signed-off-by: Brian <bmahabir@bu.edu>
---------
Signed-off-by: Brian <bmahabir@bu.edu>
* feat: add update image build to backend
this is part of a larger issue to update the image to the latest build
This pr adds the backend components needed to update the image to the latest build
Signed-off-by: Brian <bmahabir@bu.edu>
* fix: updated tests and addressed some bugs
Assisted-by: Cursor claude sonnet 4.5
Signed-off-by: Brian <bmahabir@bu.edu>
* fix: added explicit tag parameter to updateimage
imageid can have references to multiple tags. If a user clicks
on the image for the backend it should have the id and the tag
for the appropriate update. Also removed localhost string lookup
in favor of checking if an image is associated with a remote
registry
Signed-off-by: Brian <bmahabir@bu.edu>
* fix: updated repo tag tests
Assited-by: Cursor opus
Signed-off-by: Brian <bmahabir@bu.edu>
* chore: update mock console for image update
Signed-off-by: Brian <bmahabir@bu.edu>
---------
Signed-off-by: Brian <bmahabir@bu.edu>
* feat(api): add engineid to networkcreateresult
this is needed to identify what engine created the network
in order to route to the network summary page
Signed-off-by: Brian <bmahabir@bu.edu>
* chore: add/fixed tests to support networkcreateresult id
Signed-off-by: Brian <bmahabir@bu.edu>
---------
Signed-off-by: Brian <bmahabir@bu.edu>
### What does this PR do?
Uses `/Library/Application
Support/io.podman_desktop.PodmanDesktop/default-settings.json` and
`/Library/Application
Support/io.podman_desktop.PodmanDesktop/default-settings.json`
Instead of:
`/Library/Application Support/Podman Desktop/default-settings.json`
and
`/Library/Application Support/Podman Desktop/locked.json`
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
N/A
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
Fixes https://github.com/podman-desktop/podman-desktop/issues/15276
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
- [X] Tests are covering the bug fix or the new feature
1. Boot PD on **macOS**
2. Confirm that the files are being loaded / checked in the correct
location:
```sh
main ↪️ [Managed-by]: Loaded managed defaults from: /Library/Application Support/io.podman_desktop.PodmanDesktop/default-settings.json
main ↪️ [Managed-by]: Loaded managed locked from: /Library/Application Support/io.podman_desktop.PodmanDesktop/locked.json
```
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
by default, default token is not triggering GitHub actions
it means then, than pushing a tag is not starting the job
to publish npmjs packages
fixes https://github.com/podman-desktop/podman-desktop/issues/15279
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
### What does this PR do?
The titles were slightly incorrect (should be
`/usr/share/podman-desktop` not `/usr/share/containers/podman-desktop`
### Screenshot / video of UI
<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->
N/A
### What issues does this PR fix or reference?
<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->
N/A
### How to test this PR?
<!-- Please explain steps to verify the functionality,
do not forget to provide unit/component tests -->
N/A
Signed-off-by: Charlie Drage <charlie@charliedrage.com>
description: Deep investigation of CI/CD test failures - identifies root causes by analyzing logs, artifacts, git history, and source code
---
Investigate CI test failures for the given GitHub Actions run. The user will provide a run URL or run ID as: $ARGUMENTS
## Protocol
This is an adaptive-depth investigation. You gather all surface-level data in one parallel batch, classify the failure, then go only as deep as needed. An infra failure resolves in one round. A clear build error in two. A subtle UI regression gets the full trace analysis pipeline.
Wall-clock time is the enemy. Launch independent work in parallel. Never wait for one API call to decide whether to start another.
Combine the branch-name fetch with the log save to reduce tool calls:
```
# f) Branch name
gh api repos/{owner}/{repo}/actions/runs/{run-id} --jq '.head_branch'
```
**Identify failing tests from the overview first.** The `gh run view` output (call a) already contains `🧪` annotations and `X` markers with test names. Read these before touching any log files — they tell you WHAT failed without any grepping.
Then grep the saved log file for error DETAILS (locator, expected, received):
grep -B 1 -A 5 "Error:.*expect\|Error:.*Manifest\|Error:.*timeout\|Error encountered\|intercepts pointer\|no such file\|copier subprocess\|layer not known\|unable to copy" /tmp/ci-logs-{run-id}.txt | grep -v "STDERR\|echo\|npm\|curl\|jq\|matcherResult\|endWallTime\|Symbol\|stepId\|boxedStack\|stack:" | head -50
```
**`--log-failed` blind spot:** Many CI setups (podman-desktop/e2e, extension repos) mark the test step as ✓ (passed) even when Playwright reports failures — the exit code is 0 or `continue-on-error: true`. Only the "Publish Test Report" step fails (X). In this case, `--log-failed` captures the Publish step output which may NOT contain Playwright error details. The grep will return empty.
**When the grep returns empty but the overview shows test failures**, fall back immediately — don't retry different grep patterns:
1. **Download the individual job log** (contains ALL step output including the passed test step):
```
gh api repos/{owner}/{repo}/actions/jobs/{job-id}/logs > /tmp/ci-job-{job-id}.txt 2>&1
```
2. **For blob-format logs** (entire output on one line), use `grep -o` with `cut` to extract error snippets:
```
grep -o 'Error:.*expect[^\\]*' /tmp/ci-job-{job-id}.txt | cut -c1-300 | head -5
grep -o 'Locator:.*' /tmp/ci-job-{job-id}.txt | cut -c1-200 | head -5
```
3. **For Testing Farm** (Playwright runs remotely): extract JUnit XML from artifacts:
Action: Skip everything else. Write the report now. These are provisioning failures with nothing to analyze.
**B) Clear build/process error -> Report after confirming with run history**
Signals: error message is self-explanatory ("no such file or directory", "unable to copy from source docker://...", registry HTTP errors, "copier subprocess" failures). The error context page snapshot would just show a generic page.
Action: Check run history for pattern (isolated vs chronic), then report. Skip artifact download and trace analysis — the CI log error tells the whole story.
**C) UI/test failure -> Full investigation**
Signals: locator timeouts, assertion mismatches, "intercepts pointer events", strict mode violations, `expect(locator).toBeVisible()` failures. The error message says _what_ failed but not _why_.
- **Branch context:** If the run is on a feature branch (not `main`), failures may be expected during development. Check if later runs on the same branch pass — if so, it's a **resolved regression** and the fix is already in. Note this in the report and skip deep investigation.
- **Dedup:** Multiple jobs failing with the same test? Investigate one, note the rest share the root cause.
- **Multi-failure:** Multiple different failures in one job? Check if they cascade from the first (serial test block) or are independent.
- **Run history pattern:** Isolated (transient), regression (code change), chronic (systemic), alternating (flaky/environment), or **resolved** (failed then fixed — later runs pass). For resolved regressions, report what failed and note the fix, but skip deep investigation.
---
### Step 3: Artifacts + Trace Dispatch (Category C only)
Launch artifact download alongside any remaining greps. Pick the smallest artifact from a failed job that ran tests. **Skip artifacts >500MB** (videos, build outputs — will timeout). **If all artifacts show "(expired)"**, skip this entire step — older runs lose artifacts after the retention period (typically 90 days but can be as short as 1 day). You'll have to work with CI logs and run history only. Note this limitation in the report.
```
# Download + list key files in one shot
cd /tmp && gh api repos/{owner}/{repo}/actions/artifacts/{id}/zip > ci-results.zip && \
**Read error-context.md** — for UI failures (locator timeouts, assertion mismatches), this page snapshot often reveals the answer immediately. For build/process failures, skip it — the CI log error is more useful.
**Trace analysis** — if trace.zip exists, pre-extract and dispatch a background subagent:
```
mkdir -p /tmp/ci-traces/{name} && cd /tmp/ci-traces/{name} && unzip -o /path/to/trace.zip
```
Read the last 2-3 screenshots from `resources/*.jpeg | sort | tail -3`, then dispatch:
```
Agent(run_in_background=true, prompt="""
Analyze this Playwright trace for a CI test failure.
Trace: /path/to/trace.zip
Extracted: /tmp/ci-traces/{name}/
Failing test: [name from logs]
Error: [message from logs]
Error context: [paste error-context.md if available]
Screenshots: [describe what each shows]
Use the playwright-trace-analysis skill to perform the analysis.
MCP tools if available, otherwise read extracted files.
Return: failure summary, event timeline with step refs, evidence citations,
root cause [Confirmed|Likely|Unknown], failure type, recommended action with file:line.
Skip if the run history shows a chronic or isolated pattern. Launch in parallel:
1. **Verify last passing run:**`gh run view {id} --repo {owner}/{repo}`
2. **Check adjacent failures** for same test: `gh run view {id} --repo ... | grep -E "^X|🧪|❌"`
3. **Fetch test source:**`gh api repos/{owner}/{repo}/contents/{path} --jq '.content' | base64 --decode | sed -n '{start},{end}p'`
(macOS base64 fallback: pipe through `python3 -c "import sys,base64;print(base64.b64decode(sys.stdin.read()).decode())"`)
4. **Commits between pass/fail:**`git log --oneline --since="{date}" --until="{date}" -- {paths}`
---
### Step 5: Report
Collect trace subagent results if dispatched. Correlate all evidence: CI logs, error context, trace findings, test source, regression history, platform comparison. If CI logs and trace disagree, trust traces for UI failures, logs for infra.
```
## CI Failure Investigation
### Summary
One-sentence root cause.
### What Failed
| Job | Test | Error | Duration |
|-----|------|-------|----------|
### Root Cause
- **What:** ...
- **Where:** file:line
- **When introduced:** commit or "N/A — transient"
| `Missing file: host` / `MAPT container failed` / `Artemis resource ended in error` | Azure/Testing Farm VM provisioning failure | Report (Category A) |
| `Unable to download docker-compose binary: HttpErr` | GitHub API download failure; test only handles success + rate-limit | Report (Category B) |
| `overlay/.../merged: no such file or directory` / `copier subprocess` | Container storage corruption, often after "Free up disk space" step | Report (Category B) |
| `unable to copy from source docker://...` | Registry pull failure (network/rate limit) | Report (Category B) |
| `intercepts pointer events` + `fade-bg` div | Modal overlay blocking clicks; test doesn't wait for dialog dismissal | Trace analysis (Category C) |
| `strict mode violation: ... resolved to 2 elements` | Locator matches multiple DOM nodes; `.or()` compound locator issue | Error context (Category C) |
| `Expected: "RUNNING"` / `Received: "STOPPED"` | Resource never reached target state within timeout | Platform comparison |
| `Test timeout of N ms exceeded` + `Target page closed` | Long operation exceeded test timeout; browser was killed | Build/process failure |
### Platform Patterns
- **Win10 vs Win11:** Win10 CI runners are consistently slower. K8s deployments, image builds, and cluster operations often timeout on Win10 while passing on Win11 with identical code.
- **x86 vs ARM (macOS-26, Win11-ARM):** ARM runners have different timing characteristics. Tests with tight timeouts (5s) for UI rendering or provider initialization may pass on x86 but fail on ARM. If failures cluster on ARM platforms while x86 passes, suspect timing — increase timeouts.
- **WSL vs Hyper-V:** Different networking and filesystem behavior.
- **Linux (Testing Farm) vs Windows:** Different artifact layouts, auth file paths, filesystem watchers. No error-context.md on Testing Farm — use JUnit XML.
- **GPU vs Default (Testing Farm):** GPU pool has been chronically unavailable. If only GPU jobs fail with provisioning errors, it's infra.
- **Dev vs Prod mode:** Prod binaries may have different startup timing (minified, no sourcemaps, different Electron flags). A test passing in dev but failing in prod (or vice versa) on the same runner suggests mode-specific initialization differences.
### Workflow Patterns
- **✓ Run tests / X Publish Report:** The test step passes but the publish step fails. This means `--log-failed` won't contain Playwright errors — they're in the passed test step's log. Fall back to downloading the full job log. The `gh run view` annotations still show `🧪` with test names. This is the default pattern for podman-desktop/e2e, extension-bootc, and Testing Farm workflows.
- **X Run tests / X Publish Report:** Both fail. `--log-failed` contains Playwright errors from the test step. Grep works normally. This is the pattern for kortex, ai-lab main e2e, and workflows where the test step exits non-zero on failure.
### Noise to Ignore
- `Gtk: gtk_widget_add_accelerator: assertion failed` — Electron/Gtk compat on Linux
Scaffold a new Podman Desktop extension as a standalone repository with all
required boilerplate, build config, Containerfile, and Svelte webview. Use
when the user asks to create a new extension, add extension boilerplate,
scaffold an extension, or bootstrap a Podman Desktop extension project.
---
# Create a New Podman Desktop Extension
Scaffold a standalone extension in its own repository. The user provides an extension name and a brief description of what it should do. You produce all required files and verify the extension builds and can be loaded locally into Podman Desktop.
## Inputs
Ask the user (or infer from context):
1. **Extension name** — kebab-case identifier (e.g. `apple-container`). Used as the directory/repo name and the `name` field in `package.json`.
2. **Display name** — human-readable title (e.g. `Apple Container`).
3. **Description** — one-sentence summary shown in the extension list.
4. **Feature scope** — what the extension should do. Common patterns:
- **Minimal** — register a command, show a notification
- **Webview** — display a Svelte UI panel (this is the default for any extension that shows content)
- **Provider** — register a container engine or Kubernetes provider
- **Status bar / Tray** — add status bar entries or tray menu items
5. **Publisher** — the org or username that owns the extension (default: the user's GitHub username).
If the extension needs to display any UI beyond simple notifications, **always use the multi-package webview layout** (not inline HTML). This is the standard for all production Podman Desktop extensions.
---
## Where to look in the Podman Desktop codebase
When implementing extension features, you may need to look up API details:
| Full extension API types (`createWebviewPanel`, `containerEngine`, `provider`, etc.) | `packages/extension-api/src/extension-api.d.ts` in the podman-desktop repo |
| How extensions are published to OCI registries | `website/docs/extensions/publish/index.md` |
---
## Step 1 — Choose layout
### Minimal (no UI)
For extensions that only register commands, providers, status bar items, or configuration — no webview needed.
```
{name}/
├── .gitignore
├── Containerfile
├── LICENSE
├── README.md
├── icon.png
├── package.json
├── tsconfig.json
└── src/
└── extension.ts
```
### Multi-package with Svelte webview (default for any UI)
**Always use this layout when the extension displays content.** Do not use inline HTML strings. The frontend is a Svelte app built by Vite into static assets that the backend loads into a webview panel.
```
{name}/
├── .gitignore
├── Containerfile
├── LICENSE
├── README.md
├── package.json # root workspace — runs both packages
├── packages/
│ ├── backend/ # the extension entry point (Node.js)
│ │ ├── icon.png
│ │ ├── package.json # has "main": "./dist/extension.js"
│ │ ├── tsconfig.json
│ │ ├── vite.config.ts
│ │ └── src/
│ │ └── extension.ts
│ ├── frontend/ # Svelte app built into backend/media/
export async function deactivate(): Promise<void> {
console.log('stopping {name} extension');
}
```
**Why this approach?** The webview runs in a sandboxed iframe with its own origin. Local file paths don't resolve — you must convert them with `panel.webview.asWebviewUri()` and set `localResourceRoots` to grant access to the `media/` folder.
### Backend-to-frontend messaging
The backend can send messages to the frontend with `postMessage`, and the frontend listens with `window.addEventListener('message', ...)`:
The frontend can also send messages back to the backend using `acquirePodmanDesktopApi().postMessage()`, and the backend receives them via `panel.webview.onDidReceiveMessage`. See the [full template](https://github.com/podman-desktop/podman-desktop-extension-full-template) for a complete RPC implementation using `MessageProxy`.
The OCI image copies from `packages/backend/` (the extension manifest lives there), plus the `media/` folder that contains the built frontend assets.
---
## Step 5 — Build and verify
```bash
npm install
npm run build
```
After building, verify:
- `packages/backend/dist/extension.js` exists (the backend)
- `packages/backend/media/index.html` exists (the built frontend)
---
## Step 6 — Test locally in Podman Desktop
1. Open Podman Desktop
2. Go to **Settings > Preferences > Extensions** and enable **Development mode**
3. Go to **Extensions > Local Extensions** tab
4. Click **Add a local folder extension...** and select the folder containing the extension `package.json`:
- **Multi-package layout:** select `packages/backend/` (not the root)
- **Minimal layout:** select the repository root
5. Verify the extension appears as `ACTIVE`
6. Test the extension's functionality
---
## Step 7 — Package and publish (when ready)
```bash
npm run build
podman build -t quay.io/{publisher}/{name} .
podman push quay.io/{publisher}/{name}
```
To add it to the official catalog, open a PR on [podman-desktop-catalog](https://github.com/podman-desktop/podman-desktop-catalog) adding the extension to `static/api/extensions.json`.
---
## Minimal extension (no webview)
For extensions without a UI panel, use the single-package layout from Step 1. Same `package.json` / `vite.config.ts` patterns as the backend package, minus the `media/` loading.
| Pull a container image | `extensionApi.containerEngine.pullImage(connection, image, callback)` |
| Create a container | `extensionApi.containerEngine.createContainer(engineId, options)` |
| Start/stop a container | `extensionApi.containerEngine.startContainer(engineId, id)` |
| List containers | `extensionApi.containerEngine.listContainers()` |
| Get running engine connection | `extensionApi.provider.getContainerConnections()` |
| Get engine ID from connection | `extensionApi.containerEngine.listInfos({ provider: connection })` |
| Navigate to webview | `extensionApi.navigation.navigateToWebview(webviewId)` |
---
## Common pitfalls
### Getting the `engineId` for container operations
Many `containerEngine` methods (`createContainer`, `startContainer`, `stopContainer`, `deleteContainer`, `inspectContainer`) require an `engineId` string. This is **not**`connection.name` from `getContainerConnections()` — that will produce a "no engine matching this container" error.
Alternatively, if you already have containers or images from `listContainers()` or `listImages()`, their `engineId` field can be reused directly.
### `createContainer` auto-starts by default
`ContainerCreateOptions.start` defaults to `true`. If you call `createContainer` followed by `startContainer`, the second call will fail with **HTTP 304** ("container already started"). Either:
- Rely on the default and skip `startContainer`, or
- Pass `start: false` in the create options if you need to configure the container before starting it
For the full API surface, see [`extension-api.d.ts`](https://github.com/podman-desktop/podman-desktop/blob/main/packages/extension-api/src/extension-api.d.ts).
- **Full (Svelte + Tailwind + multi-package):** [podman-desktop-extension-full-template](https://github.com/podman-desktop/podman-desktop-extension-full-template) — this is the recommended starting point for any extension with a UI.
The `waitForPodmanMachineStartup` utility handles this by resetting via CLI. If tests time out waiting for RUNNING state, check that Podman is installed and the machine provider is available.
### No Container Engine
Some POM methods (e.g. `openPullImage`) use `waitWhile(() => this.noContainerEngine())` to gate on engine availability. If tests fail with "No Container Engine", the Podman machine likely didn't start.
### Platform-specific skips
Use helpers from `/@/utility/platform`:
```typescript
import { isLinux, isMac, isWindows, isCI } from '/@/utility/platform';
test.skip(isLinux, 'Not supported on Linux');
```
## Additional Resources
- For the project's wait utilities, operation helpers, and framework API, see [references/reference.md](references/reference.md)
- For concrete examples from actual spec files, see [references/examples.md](references/examples.md)
These are mutually exclusive: `PODMAN_DESKTOP_BINARY` takes precedence.
### Tracing and Video
- `runner.setVideoAndTraceName('feature-e2e')` — call in `beforeAll` to name artifacts
- On `runner.close()`: tracing stops, video saves, process terminates
- By default, traces and videos are deleted on pass unless `KEEP_TRACES_ON_PASS` / `KEEP_VIDEOS_ON_PASS` env vars are set, or `RunnerOptions` has `saveTracesOnPass: true` / `saveVideosOnPass: true`
Analyzes Playwright trace archives (`trace.zip`) to diagnose test failures,
flaky behavior, and unexpected UI states using trace steps, console output,
network activity, and screenshots. Use when the user provides a trace path or
trace artifact, asks why a Playwright or E2E test failed, wants root-cause
analysis from CI artifacts, mentions the trace viewer, or asks whether a
failure is flaky or an application bug.
---
# Playwright Trace Analysis
## When to use
Apply when the user provides:
- A `trace.zip` path
- A trace artifact to inspect
- A failing Playwright/E2E test and asks for root-cause analysis from the trace
- Two traces to compare, such as passing vs failing or retry-0 vs retry-1
## Immediate behavior
If the user already provided a usable trace path or attached trace artifact, start analysis immediately.
Do **not** ask for extra context up front unless one of these is true:
- The trace path is missing
- The path is ambiguous or unresolved
- The user supplied multiple traces and did not say which one to analyze
Optional context like test title, CI log, expected behavior, or retry history can help, but it is not required for the first analysis pass.
## Inputs
- Absolute path to `trace.zip`
- Or a workspace-relative path you can resolve safely
- Optional: test title, spec file, CI snippet, expected behavior, retry history, second trace
If the user points to a directory instead of a zip, locate the trace archive inside it before analyzing. If multiple candidate zips exist, ask one focused follow-up question.
## MCP tools
Use the `user-playwright-analyzer` MCP server.
Before the first MCP call in a session, read the server tool descriptors from the Cursor MCP directory and use the schema exactly as written. Do not guess parameter names.
| `get-screenshots` | Relevant screenshots around errors and critical actions | — |
| `view-screenshot` | Inspect one screenshot by filename | `filename` |
| `get-raw-trace-paginated` | Raw trace when filtered output is insufficient | `browserIndex`, `page`, `pageSize` |
| `get-raw-network-paginated` | Raw network when filtered output is insufficient | `browserIndex`, `page`, `pageSize` |
### MCP fallback — manually-created traces
Some test frameworks create traces manually using Playwright's tracing API (`tracing.start()` / `tracing.stop()`) rather than relying on Playwright's built-in per-test trace mechanism. These traces are structurally valid but may use naming conventions or internal layouts that the MCP tool does not recognize.
**When the MCP tool returns "No trace files found" or similar errors but the zip does contain `trace.trace` / `trace.network` files, fall back to manual analysis.** Do not assume the trace is empty or broken — verify by listing the zip contents first.
See the [Manual trace parsing](#manual-trace-parsing) section below and [reference.md](reference.md) for the detailed file format and parsing scripts.
### Escalation rules
Prefer the smallest useful call sequence:
1. `analyze-trace`
2. If the MCP tool returns errors or empty results, verify the zip contents (`unzip -l`) and fall back to [manual trace parsing](#manual-trace-parsing)
3. `get-trace` with `filterPreset: "minimal"` if the overview is not enough
4. One or more corroborating calls based on the failure signal:
- `get-screenshots` for locator, visibility, or wrong-page problems
- `get-network-log` for failed or missing requests
- `get-trace` with `filterPreset: "moderate"` for console-heavy or sequence-heavy failures
5. `get-trace` with `filterPreset: "conservative"` only if prior calls are still inconclusive
6. Raw paginated tools only as a last resort
Avoid jumping to `raw: true` early. Large raw payloads are harder to reason about and more likely to be truncated.
### Parallel tool calls
When the overview suggests you need multiple corroborating signals, call them in parallel rather than sequentially. For example, if a locator timed out and you suspect both a visual issue and a network issue, call `get-screenshots` and `get-network-log` in the same tool-call batch.
Good parallel combinations:
- `get-screenshots` + `get-network-log` — locator timeout with possible data-loading cause
- `get-screenshots` + `get-trace` (moderate) — wrong visual state with unknown trigger
- `get-network-log` + `get-trace` (moderate) — API failure with unclear console context
Do not parallelize calls that depend on each other's output (e.g., don't call `view-screenshot` until you know the filename from `get-screenshots`).
## Standard workflow
### Step 1: Run the overview
Call `analyze-trace` first and extract:
- The failing test or action if available
- The exact error text
- The first meaningful failing step
- Any obvious screenshot or network clues
- Action durations — note any step that took significantly longer than its peers
### Step 2: Read the test source
Once you know the failing test file and approximate line, read the relevant spec file and any page objects it uses. This gives you:
- **Intent**: what the test was trying to verify
- **Locator context**: whether the locator is reasonable or brittle
- **Assertion context**: whether the expected value still makes sense
- **Flow context**: what earlier steps should have set up the state for the failing assertion
If the test file path is not in the trace output, search the workspace for the test name or assertion text.
### Step 3: Find the first meaningful failure
Prioritize the earliest causal failure, not the later cascade.
Build a mental timeline by mapping:
1. The last successful action before the failure
2. Any console errors or warnings between success and failure
3. Any network requests initiated or completed in that window
4. The screenshot state at the moment of failure
Examples of likely causal signals:
- Assertion mismatch
- Locator timeout or actionability failure
- Navigation timeout or unexpected URL
- Console exception before the failing assertion
- 4xx/5xx request or a required request never being sent
- Action duration spike (a step taking 10x longer than similar steps)
### Step 4: Corroborate with additional signals
Before concluding, check at least one additional source unless the trace already contains a direct smoking gun.
| MCP returns "No trace files found" or similar error | List zip contents with `unzip -l`; if `trace.trace` exists, use [manual trace parsing](#manual-trace-parsing) |
| Clear assertion mismatch and obvious cause in overview | Report it; extra MCP calls may be unnecessary |
| Locator timeout or hidden element | Run `get-screenshots` |
| Overview mentions console errors but not enough context | Run `get-trace` with `filterPreset: "minimal"` or `"moderate"` |
| Network summary shows 4xx/5xx or missing response | Run `get-network-log` |
| Screenshot looks wrong but not enough detail | Run `view-screenshot` for the named frame |
| Filtered output omits the needed detail | Escalate to `conservative`, then raw paginated tools |
| Multiple browser sessions exist | Use `browserIndex` on paginated raw tools |
| Failure looks like a regression | Check git history for the affected file |
| Test source uses a brittle locator | Read the spec file and propose a resilient alternative |
| CI artifact is a nested zip (not a direct trace zip) | Extract the inner trace zip first, then analyze |
| Multiple runs fail the same way | Do **not** default to flaky; run [exhaustive console analysis](#exhaustive-console-analysis) across all traces |
## Common patterns
### Locator and actionability failures
- `waiting for locator(...)` then timeout: element never appeared, selector changed, or page never reached the expected state
- A single action taking 5-10x longer than peers: likely waiting on a network response, animation, or resource load
- Gradual slowdown across steps: possible memory leak or resource exhaustion
- Timeout at exactly the configured limit (e.g., 30000ms): the condition was never met, not just slow
### Electron-specific patterns
- **IPC failures**: console errors mentioning `ipcRenderer`, `ipcMain`, or channel names indicate broken communication between main and renderer processes
- **Webview loading**: if the test interacts with a webview, check whether the webview's `document` loaded (look for webview-related console messages or navigation events)
- **Multi-window issues**: Electron apps can have multiple `BrowserWindow` instances; verify the trace is from the correct window
- **Preload script errors**: errors during preload indicate the renderer lacks expected APIs — check console output for preload-related messages
### Flakiness indicators
Treat as likely flaky only when the trace suggests timing or nondeterminism, for example:
- Screenshot shows spinner/loading/skeleton instead of final UI
- Expected state appears after the timeout window
- Animation or transition seems to block the action
- Request ordering matters and looks variable
- Retry history or CI context indicates pass-on-retry behavior
If you suspect flakiness, say why and recommend the stabilization point, such as waiting for a specific response, element state, or post-animation condition.
### Deterministic failures across multiple runs
When multiple traces from separate CI runs are provided and they all fail the same way, **raise the bar significantly before classifying as flaky**. A failure that reproduces N/N times across independent runs is almost certainly deterministic. Even if the test has `continue-on-error: true` or is known to be occasionally flaky, consistent reproduction points to an app bug or environment regression — not timing luck.
In this scenario:
1. **Do not default to "likely flaky"** — consistent reproduction is strong counter-evidence against flakiness.
2. **Perform an exhaustive console log scan** (see [Exhaustive console analysis](#exhaustive-console-analysis) below) before drawing conclusions. The root cause often hides in a log-level message that a severity-filtered search misses.
3. **Look for a common causal event** across all traces rather than analyzing each in isolation. If the same console error, network failure, or UI state appears in every trace, that is almost certainly the root cause.
4. Classify as flaky only if the traces show genuinely different failure modes or if some runs pass and others fail.
## Reporting contract
Every analysis must include all of the sections below. The report should be structured so a developer can read it top-to-bottom in under 2 minutes and know exactly what happened, why, and what to do.
### Required sections
1. **Failure summary** — One or two sentences: what failed and the most likely cause.
2. **Event timeline** — A compact chronological sequence of the key events leading to the failure. Include timestamps or step numbers when available. This gives the reader the narrative arc.
3. **Evidence** — Each claim must cite a specific artifact from the trace. Use this format:
- `[trace step N]` — reference to a specific action or event in the trace
- `[screenshot: filename]` — reference to a screenshot, with a brief description of what it shows
- `[network: METHOD url → status]` — reference to a specific request
- `[console: level] message` — reference to a console log entry
4. **Root cause** — A confidence-labeled explanation. Format: `[Confirmed|Likely|Unknown] explanation`. If `Likely` or `Unknown`, briefly state what additional evidence would upgrade the confidence.
5. **What was ruled out** — Briefly list alternative hypotheses you investigated and why they don't fit. This builds trust in the conclusion and saves the developer from re-investigating dead ends.
6. **Recommended action** — A specific, actionable fix. When the fix is in test code, include the file path, the problematic line or locator, and the suggested replacement. When the fix is in application code, point to the relevant source file and describe the expected behavior change.
### Report template
Use markdown headers matching the required sections above. Cite evidence with these prefixes: `[trace step N]`, `[screenshot: filename]`, `[network: METHOD url → status]`, `[console: level] message`. See [reference.md](reference.md) for the full citation format reference.
For test code fixes, include the file path, problematic line/locator, and suggested replacement. For app code fixes, point to the relevant source file and describe the expected behavior change.
### Severity annotation (optional but encouraged)
When context is available, annotate the failure with severity:
- **Blocking**: test suite cannot proceed, or the failure indicates a critical app regression
- **Significant**: test fails reliably, indicating a real but non-critical issue
- **Minor**: cosmetic or low-impact, or the test itself is overly strict
- **Infra-only**: failure is caused by CI environment, not application or test code
## Multi-trace comparison
When two traces are provided:
1. Run `analyze-trace` on both (in parallel)
2. Find where their step sequences diverge
3. Compare screenshots and network behavior at the divergence point
4. Report the **delta**, not two separate full summaries
Focus on: "the failing trace diverges here, and this is the first difference that plausibly explains the failure."
### Retry-trace comparison
When Playwright retries produce multiple traces for the same test:
1. Compare the traces to determine whether the failure is consistent or intermittent
2. If the retry passes, focus on what differs — typically network timing, element ordering, or data availability
3. A consistent failure across retries is likely deterministic; a pass-on-retry is likely flaky
4. Report the specific divergence point and the stabilization needed
### Batch analysis
When multiple traces from a CI run are provided:
1. Run `analyze-trace` on each (in parallel, up to 3-4 at a time)
2. Look for common failure patterns — same error message, same failing API endpoint, same console exception
3. Group failures by root cause rather than reporting each individually
4. If a single root cause explains multiple failures, say so explicitly and list the affected tests
## If the trace is insufficient
State that directly. Good examples:
- "The trace shows the assertion timing out, but not why the data never loaded."
- "I can confirm the UI was still loading, but I cannot tell from this trace alone whether the delay came from the app or the test environment."
Then name the single best next action:
- Escalate `get-trace` to `moderate` or `conservative`
- Inspect `get-network-log` (possibly with `raw: true` if the filtered version omits relevant requests)
- Compare with a passing trace
- Review the failing locator or assertion in the test source
- Check for a video artifact alongside the trace
- Look at CI runner logs for environment issues (OOM, disk, network)
Do not leave the analysis open-ended. Always propose a concrete next step even when the trace is insufficient.
## Exhaustive console analysis
Console messages in Playwright traces carry a `messageType` field (`log`, `debug`, `info`, `warning`, `error`). **Do not filter solely by `error` or `warning` severity.** Application code frequently logs critical errors at `log` or `info` level — for example, a `catch` block that calls `console.log(\`Error while ...: ${err}\`)`instead of`console.error(...)`. Filtering only by severity will miss these, potentially causing you to misdiagnose the failure entirely.
### Required console scanning procedure
When performing manual trace parsing, always run **two passes** over console messages:
1. **Severity pass** — collect all `error` and `warning` messages.
2. **Keyword pass** — collect messages at **any** severity level whose text matches failure-related patterns. Use a broad keyword set:
Report the union of both passes. When a message appears at an unexpected severity (e.g., an error message at `log` level), flag the mismatch explicitly — it often indicates a swallowed error in the application code that is central to the failure.
### Why this matters
A real-world example: `TypeError: fetch failed` from the Kubernetes client was logged via `console.log()` (not `console.error()`). Filtering only for `error`-level messages missed it entirely, leading to a misdiagnosis of "test flakiness / timing issue" when the actual root cause was the app's `fetch()` calls failing due to a build configuration change. The error was present in all traces and was the direct cause of "Cluster not reachable" — but it was invisible to a severity-only filter.
## Manual trace parsing
When the MCP tool cannot parse the trace (common with manually-created traces), analyze the files directly. The trace zip typically contains three components: `trace.trace`, `trace.network`, and `resources/` with screenshots.
### Step 1: Verify zip contents and extract
```bash
unzip -l /path/to/trace.zip | head -20
```
Look for `trace.trace`, `trace.network`, and `resources/*.jpeg`. If the trace zip is nested inside a CI artifact archive, extract the inner zip first.
### Step 2: Parse actions and locator resolutions from trace.trace
The `trace.trace` file is newline-delimited JSON. Each line is an object with a `type` field. The key types for failure analysis are `before` (action start), `after` (action result), `log` (Playwright internal logs), and `console` (browser console output). See [reference.md](reference.md) for the full format specification and ready-to-use parsing scripts.
Extract the action timeline and errors:
```bash
python3 -c "
import json
with open('trace.trace') as f:
for line in f:
obj = json.loads(line.strip())
t = obj.get('type', '')
if t == 'before':
cid = obj.get('callId', '')
api = obj.get('apiName', '')
sel = obj.get('params', {}).get('selector', '')[:100]
**Important:** The console extraction above scans messages at **all** severity levels for failure-related keywords, not just `error`/`warning`. This is essential — application code may log critical errors via `console.log()` rather than `console.error()`. See [Exhaustive console analysis](#exhaustive-console-analysis) for the rationale.
The `log` entries with "locator resolved to" are critical — they show exactly which DOM element Playwright matched for each retry of an assertion. Repeated resolution to a hidden or wrong element (as seen in `.first()` matching a `class="hidden"` span) is a strong signal for locator bugs.
### Step 3: View screenshots at specific timestamps
Screenshot filenames encode timestamps: `page@<hash>-<timestamp>.jpeg`. Use the timestamps to correlate with trace events, or use `view-screenshot` from the MCP tool (which still works even when trace parsing fails).
### Step 4: Check network log
```bash
python3 -c "
import json
with open('trace.network') as f:
for line in f:
obj = json.loads(line.strip())
snap = obj.get('snapshot', {})
url = snap.get('request', {}).get('url', '')
status = snap.get('response', {}).get('status', '')
For Electron apps, the network log typically only captures renderer-process requests (local `file://` resource loads). API calls made by the main process (e.g., Octokit calls to GitHub) are not captured in the trace.
## CI artifact structure
CI artifacts nest traces inside larger archives. Extract the inner trace zip before analyzing. See [reference.md](reference.md) for the full layout, `json-results.json` parsing scripts, and `error-context.md` usage.
| `resources/` | Screenshots (JPEG), snapshot HTML, and media referenced by the trace |
When MCP tools can parse the trace, use them. When they cannot (common with manually-created traces — see below), parse the files directly using the format specification in this section.
## Manually-created vs automatic traces
Playwright supports two trace creation modes:
1. **Automatic** (per-test): configured via `playwright.config.ts` with `trace: 'on'` or `trace: 'retain-on-failure'`. Playwright creates one trace per test with rich metadata (test name, step annotations, source locations). MCP tools are designed for this format.
2. **Manual** (API-driven): the test framework calls `page.context().tracing.start()` and `tracing.stop({ path })` explicitly. This produces a valid trace zip but may lack per-test metadata, use continuous recording across multiple tests, or use non-standard file naming. The MCP tool may report "No trace files found" for these.
**Always verify the zip contents with `unzip -l` before concluding a trace is empty.** If `trace.trace` and `trace.network` exist, the data is there — it just needs manual parsing.
## trace.trace file format
Newline-delimited JSON. Each line is a self-contained JSON object with a `type` field.
locator resolved to <spancontenteditable="false"class="hidden s-qNHuh0m3pQVo">...</span>
```
These entries are the most diagnostic for locator bugs. When the same `callId` produces repeated `log` entries showing resolution to the same element, it means Playwright is retrying the assertion and consistently matching that element. If the element is hidden or wrong, this reveals the root cause.
Note: in Electron apps, console messages from the main process are forwarded to the renderer with a `main ↪️` prefix. These are often truncated in the `preview` field.
### Parsing scripts
**Full action timeline with errors and key logs:**
```python
import json
with open('trace.trace') as f:
for line in f:
obj = json.loads(line.strip())
t = obj.get('type', '')
if t == 'before':
cid = obj.get('callId', '')
api = obj.get('apiName', '')
sel = obj.get('params', {}).get('selector', '')[:120]
print(f'[{cid}] BEFORE {api} selector={sel}')
elif t == 'after':
cid = obj.get('callId', '')
err = obj.get('error')
if err:
print(f'[{cid}] AFTER error={err}')
elif t == 'log':
msg = obj.get('message', '')[:200]
if any(k in msg.lower() for k in ['error', 'fail', 'timeout', 'locator resolved']):
print(f' LOG: {msg}')
elif t == 'console':
args = obj.get('args', [])
text = args[0].get('preview', '')[:200] if args else ''
msgtype = obj.get('messageType', '')
if msgtype == 'error' or 'rate limit' in text.lower():
print(f' CONSOLE [{msgtype}]: {text}')
```
**Summary of entry types (useful for orientation):**
```python
import json
from collections import Counter
types = Counter()
with open('trace.trace') as f:
for line in f:
obj = json.loads(line.strip())
types[obj.get('type', 'unknown')] += 1
for t, c in types.most_common():
print(f'{t}: {c}')
```
## trace.network file format
Newline-delimited JSON. Each line is a `resource-snapshot` entry with HAR-like structure:
**Electron caveat:** For Electron apps, the network log typically only captures renderer-process requests — local `file://` loads for CSS, JS, fonts, and images. API calls made by the main process (e.g., Octokit calls to GitHub, Docker API calls) are **not** captured because they run in Node.js, not the browser context. Do not expect to find external HTTP traffic here.
## Screenshot naming and timestamps
Screenshots in `resources/` follow the pattern:
```
page@<context-hash>-<unix-timestamp-ms>.jpeg
```
The timestamp is a Unix epoch in milliseconds. Use it to:
- Correlate screenshots with trace events (match against `wallTime` in `before` entries)
- Calculate elapsed time between screenshots
- Identify the visual state at any point during the test
To find screenshots around a specific event, compute the target timestamp from the trace and select the nearest screenshot filenames.
## CI artifact structure
CI runs typically package results in an outer archive containing multiple files. The trace zip is nested inside:
```
ci-artifact.zip
└── results/
└── podman-desktop/
├── traces/<name>_trace.zip ← the Playwright trace
├── videos/<name>.webm ← screen recording
├── html-results/ ← Playwright HTML report
├── json-results.json ← structured test results with errors
├── junit-results.xml ← JUnit XML for CI
├── output.log ← CI build/test output
└── <test-hash>/error-context.md ← page accessibility snapshot at failure
```
### json-results.json
Contains structured test results with the exact error message and locator call log. Parse it to extract failure details:
```python
import json
with open('json-results.json') as f:
data = json.load(f)
def walk(suites):
for suite in suites:
for spec in suite.get('specs', []):
for test in spec.get('tests', []):
for result in test.get('results', []):
if result.get('status') not in ('passed', 'skipped'):
error = result.get('error', {})
print(f"FAILED: {spec['title']}")
print(f" {error.get('message', '')[:500]}")
walk(suite.get('suites', []))
walk(data.get('suites', []))
```
The error message often contains the exact locator used, the element it resolved to, and the retry count — which can directly reveal the root cause without needing to parse the trace at all.
### error-context.md
Contains the page's accessibility tree (ARIA snapshot) at the moment of failure. This shows what Playwright "saw" in the DOM, which may differ from what was visually rendered. Key uses:
- Verify whether an expected element exists in the DOM
- Check element text content and ARIA attributes
- Identify whether a dialog or overlay is present in the DOM tree
- Compare against screenshots to find discrepancies between DOM state and visual state
## MCP tool parameter reference
All tools require `traceZipPath` (string): the absolute path to the trace zip.
### analyze-trace
No additional parameters. Returns a combined overview of execution steps, network summary, and key screenshots. Always call this first.
| `filterPreset` | `"minimal"` \| `"moderate"` \| `"conservative"` | `"minimal"` | Controls how much trace data is retained (see escalation below) |
| `raw` | boolean | `false` | When `true`, returns the complete unfiltered trace including all DOM snapshots. Overrides `filterPreset`. Use only as a last resort — output can be very large. |
**Filter preset escalation:**
1. `minimal` — maximum filtering. Removes DOM snapshots and redundant entries. Retains error logs, action steps, and basic console output. Start here.
2. `moderate` — retains more console logs, context around actions, and additional event metadata. Use when `minimal` doesn't show enough detail around the failure.
3. `conservative` — retains almost everything except raw DOM snapshots. Use for complex failures where prior levels are inconclusive.
4. `raw: true` — completely unfiltered. Only use when even `conservative` is insufficient. Prefer the paginated tool instead to avoid output truncation.
| `browserIndex` | number | `0` | Browser session index (for multi-browser traces) |
| `page` | number | `1` | Page number (1-based) |
| `pageSize` | number | `50` | Number of trace entries per page |
Use when filtered trace tools lack the detail you need. Paginate through the full raw trace without hitting output size limits. Start at page 1 and increment until you find the relevant section, or jump to later pages if you know the failure occurred late in the test.
| `browserIndex` | number | `0` | Browser session index |
| `page` | number | `1` | Page number (1-based) |
| `pageSize` | number | `20` | Number of network requests per page |
Same pagination approach as the raw trace tool. Useful when the filtered network log omits requests you suspect are relevant (e.g., requests to third-party auth providers).
## Signal correlation matrix
When diagnosing a failure, cross-reference signals from multiple sources:
| Primary signal | Secondary signal to check | What the combination reveals |
| Assertion mismatch (trace step) | Network response body | Whether the API returned unexpected data |
| Console error/exception | Trace step before it | Which user action or navigation triggered the error |
| Network 4xx/5xx | Trace steps after it | Whether the test continued despite the failure (missing error handling) |
| Network timeout/no response | Screenshot | Whether the UI shows a loading state or error message |
| Blank page in screenshot | Console output | Whether there's an uncaught exception or module load failure |
| Wrong URL in trace step | Network log | Whether a redirect occurred or navigation was intercepted |
| Slow action duration | Network log at same time | Whether a pending request is blocking the UI |
| Slow action duration | Console output | Whether a heavy computation or error-retry loop is running |
| IPC/preload error in console | Trace steps around it | Which renderer action triggered the IPC failure |
## Minimal sufficient analysis
Unless the overview is already conclusive, a good first-pass analysis usually contains:
1. One `analyze-trace` result
2. The test source code read and understood
3. One or two corroborating signals from screenshots, console/steps, or network
4. A confidence-labeled conclusion with a concrete next step
Avoid dumping all available artifacts when one or two focused follow-up calls are enough.
## Source code correlation
After identifying the failing step, always read the test source to understand intent:
1. **Spec file**: read the test function containing the failure. Check whether the assertion and locator are reasonable given the current app state.
2. **Page objects**: if the failing action is in a POM method, read that method to understand what it does and what locators it uses.
3. **App source**: if the trace points to an app-side issue (wrong rendering, missing data, console exception), navigate to the relevant component or module.
This step prevents misdiagnosis. A locator timeout might look like an app bug from the trace alone, but reading the test source reveals the locator targets a removed element (test bug).
## Timing and duration analysis
Trace steps include duration information. Use it to identify:
| Duration pattern | Likely cause | Investigation |
| Single step 5-10x slower than peers | Waiting on network, animation, or resource | Check network log for pending request at that time |
| Gradual slowdown across all steps | Memory leak, DOM bloat, or resource exhaustion | Check console for warnings; compare early vs late step durations |
| Step hits exact timeout (e.g., 30000ms) | Condition was never met | Focus on _why_ it wasn't met, not the timeout itself |
| All steps slow | CI runner under load, or app startup not complete | Check if the first action also took unusually long |
| Click takes >2s | Element not yet actionable, or animation in progress | Check screenshot for overlay, spinner, or disabled state |
## Interpreting screenshots
When viewing screenshots from `get-screenshots` or `view-screenshot`, look for:
| Race between data load and assertion | Assertion step fires while network request is still pending | Wait for the network response or use `expect` with auto-retry |
| Animation/transition timing | Click targets an element that's mid-animation | Add `waitFor({ state: 'stable' })` or wait for animation class removal |
| Non-deterministic list ordering | `toHaveText` fails because items rendered in different order | Sort before comparing, or use `toContainText` for individual items |
| Websocket reconnection | Console shows disconnect/reconnect around failure | Wait for connection re-establishment before asserting |
| Shared state between tests | Test passes in isolation but fails in suite | Check for missing cleanup in `afterEach`/`afterAll` |
| Viewport-dependent rendering | Element off-screen on CI runner's viewport size | Check viewport config; use `scrollIntoViewIfNeeded` |
| Stale Electron IPC state | First test passes, later test sees stale data from previous test's IPC calls | Ensure proper state reset between tests |
### Confirming flakiness vs deterministic failure
A failure is more likely **deterministic** if:
- It reproduces on every retry (check CI retry history).
- The trace shows a clear app error (500 response, unhandled exception).
- The expected value in the assertion is fundamentally wrong (code change broke the contract).
A failure is more likely **flaky** if:
- It passes on retry without code changes.
- The trace shows the correct state arriving _after_ the assertion timeout.
- Network response times vary significantly between runs.
### Retry trace analysis
When multiple trace files exist for the same test (retry-0, retry-1, etc.):
1. Run `analyze-trace` on each retry's trace in parallel
2. Identify whether the failure is identical across retries (same step, same error, same screenshot state)
3. If the failure differs between retries, focus on what varies — this points to the nondeterministic factor
4. If a later retry passes, the failing retry's trace shows the flaky window — identify the timing-sensitive point
## Electron and Podman Desktop patterns
### IPC communication failures
- Console messages containing `ipcRenderer`, `ipcMain`, or channel name strings indicate IPC issues
- A missing or undefined return value from an IPC call causes downstream rendering failures
- Check whether the preload script exposed the expected API by looking for preload-related console errors
### Webview interactions
- Webviews in Electron have separate document contexts; a locator targeting the main page won't find webview content
- If the trace shows a click on a webview element that doesn't respond, the webview may not have finished loading
- Look for webview navigation events and `dom-ready` signals in console output
### Extension loading
- Extensions load asynchronously; tests that depend on extension-provided UI must wait for the extension to activate
- Console messages about extension activation, provider registration, or extension errors are key signals
- A missing provider or command often means the extension failed to load rather than an app bug
### Multi-window
- Electron apps can spawn multiple `BrowserWindow` instances
- Verify the trace corresponds to the correct window (check URL, page title, or content in screenshots)
- If the trace shows actions on the wrong window, the test's page reference may have shifted
## Git history correlation
When a failure looks like a regression, use git history to narrow the cause:
```bash
git log --oneline -10 -- path/to/affected/file
git log --oneline --since="3 days ago" -- path/to/affected/directory/
```
Useful when:
- The test was previously passing and started failing without test code changes
- The locator targets something that may have been renamed or restructured
- The assertion's expected value may be outdated after a product change
Include the relevant commit in the report when it strengthens the root cause explanation.
## CI artifact locations
Traces from this project's CI are typically stored at:
The naming pattern is `{videoAndTraceName}_trace.zip`, set by the test runner. Traces for passing tests are removed by default unless `KEEP_TRACES_ON_PASS` is set.
Other CI artifacts that may complement trace analysis:
// Read/write containers directory access (ability to save the application preferences)
@ -225,6 +232,8 @@ const config = {
'--talk-name=org.kde.StatusNotifierWatcher',
// Allow to interact with Flatpak system to execute commands outside the application's sandbox
'--talk-name=org.freedesktop.Flatpak',
// required to fix cursor scaling on wayland https://github.com/electron/electron/issues/19810 when the user uses --socket=wayland in their flatpak run
git commit -s --amend -m "chore: bump version to ${bumpedVersion}"
git push origin "${bumpedBranchName}"
echo -e "📢 Bump version to ${bumpedVersion}\n\n${{ steps.TAG_UTIL.outputs.desktopVersion }} has been released.\n\n Time to switch to the new ${bumpedVersion} version 🥳" > /tmp/pr-title
4. **Format code:** Run `pnpm lint-staged` before committing
### Testing Requirements
- **Unit tests** are mandatory for new features (Vitest)
- **E2E tests** required for UI workflows (Playwright)
- Maintain or improve code coverage
- Test on multiple platforms when possible (macOS, Linux, Windows)
### Code Style
- TypeScript strict mode enforced
- Use Svelte 5 runes syntax (`$state`, `$derived`, `$effect`)
- Follow ESLint and Biome rules
- Tailwind CSS for styling (no custom CSS unless necessary)
### ESLint Rules
Before writing or modifying code, always check `eslint.config.mjs` to understand which linting rules are active. Rules vary by file type and package — consult the config directly rather than assuming defaults.
### Svelte Reactive Patterns
When setting a variable reactively, prefer in this order:
1. **`$derived` (with optional `await`)** — use when the value can be computed from existing state or an async source. Svelte 5.36+ supports `await` inside `$derived`.
2. **`onMount`** — use when you need to fetch or set a value once after the component mounts and `$derived` is not applicable.
3. **`$effect`** — use only as a last resort for side effects that cannot be expressed as a derivation.
```ts
// ✅ Preferred: $derived (sync or async)
let items = $derived(await fetchItems());
// ✅ Acceptable: onMount when $derived does not fit
let items = $state<Item[]>([]);
onMount(async () => {
items = await fetchItems();
});
// 🚫 Avoid: $effect for setting variables
let items = $state<Item[]>([]);
$effect(() => {
fetchItems().then(result => {
items = result;
});
});
```
> **Note:**`$derived` variables are read-only — you cannot reassign them (e.g. `items = [something]` will be a compile error). If you need to mutate the variable elsewhere in the component (e.g. in response to a user action), use `$state` + `onMount` instead:
>
> ```ts
> // 🚫 Won't work — cannot assign to a $derived variable
> let items = $derived(await fetchItems());
> items = []; // ❌ compile error
>
> // ✅ Use $state + onMount when you also need to write to the variable
> let items = $state<Item[]>([]);
> onMount(async () => {
> items = await fetchItems();
> });
> // later in the component:
> items = []; // ✅ fine
> ```
### Testing Patterns
- When mocking modules, use `vi.mock(import('./path/to/module'))` (with a dynamic `import()` expression) instead of `vi.mock('./path/to/module')` (string literal). This provides better type inference and IDE support.
- Use `vi.mocked(fn)` to get a typed mock reference, then configure it with `.mockReturnValue()` / `.mockResolvedValue()` and assert with `expect()`.
```ts
// ✅ Preferred
vi.mock(import('node:fs'));
vi.mock(import('./Compo2.svelte'));
// 🚫 Avoid
vi.mock('node:fs');
vi.mock('./Compo2.svelte');
```
**Setting up and asserting mocks:**
```ts
import { readFileSync } from 'node:fs';
import { beforeEach, expect, test, vi } from 'vitest';
@ -65,6 +65,172 @@ async function onButtonClicked(object: Object): Promise<void> {
{/each}
```
### Usage of Icon component
The Icon component is a unified icon wrapper that supports multiple icon formats:
- FontAwesome `IconDefinition` object uses `<Fa>` from `svelte-fa`
- Font class icons strings starting with fas fa-, far fa-, fab fa- or ending with -icon Renders as `<span>` with CSS classes
- Data URI images strings starting with data:image/ Renders as `<img>`
- Svelte Components
✅ **Use this pattern:**
```ts
<scriptlang="ts">
import { CustomSVGIcon } from '/@/icons';
import { faGear } from '@fortawesome/free-solid-svg-icons';
import { Icon } from '@podman-desktop/ui-svelte/icons';
</script>
<Iconicon={CustomSVGIcon}size="2x"/>
<Iconicon={faGear}size="xs"/>
```
🚫 **Instead of:**
```ts
<scriptlang="ts">
import { CustomSVGIcon } from '/@/icons';
import { faGear } from '@fortawesome/free-solid-svg-icons';
import Fa from 'svelte-fa';
</script>
<CustomSVGIconsize='2x'/>
<Fasize="xs"icon={faGear}/>
<iclass="fas fa-angle-down"></i>
```
Use typescript imports rather than string definitions
✅ **Use this pattern:**
```ts
<scriptlang="ts">
import { faGear } from '@fortawesome/free-solid-svg-icons';
import { Icon } from '@podman-desktop/ui-svelte/icons';
</script>
<Iconicon={faGear}/>
```
🚫 **Instead of:**
```ts
<scriptlang="ts">
</script>
<iclass="fas fa-gear"></i>
```
Another example:
✅ **Use this pattern:**
```ts
<scriptlang="ts">
import { Icon } from '@podman-desktop/ui-svelte/icons';
interface Props {
icon: unknown;
}
let { icon }: Props = $props();
</script>
<Iconicon={icon}/>
```
🚫 **Instead of:**
```ts
<scriptlang="ts">
import Fa from 'svelte-fa';
interface Props {
icon: unknown;
}
let { icon }: Props = $props();
</script>
{#if isFontAwesomeIcon(icon)}
<Faicon={icon}size="4x"/>
{:else}
{@const IconComponent = icon}
<IconComponentsize='42'/>
{/if}
```
### Using async/await in expressions
As of Svelte 5.36+, you can use the `await` keyword directly inside component expressions in three places: at the top level of the component's `<script>`, inside `$derived(...)` declarations, and inside your markup. This enables cleaner code without needing explicit promise handling.
✅ **Use this pattern:**
```ts
<scriptlang="ts">
async function fetchData(): Promise<Data> {
// async logic here
return data;
}
let data = $derived(await fetchData());
</script>
<p>Data: {data}</p>
```
🚫 **Instead of:**
```ts
<scriptlang="ts">
async function fetchData(): Promise<Data> {
// async logic here
return data;
}
// Without await, this produces a Promise
let dataPromise = $derived(fetchData());
</script>
{#await dataPromise}
<p>Loading...</p>
{:then data}
<p>Data: {data}</p>
{:catch error}
<p>Error: {error.message}</p>
{/await}
```
This is much simpler than managing promises manually and avoids the need for `{#await}` blocks when you just need the final value.
For more details on async patterns in Svelte, see the [Svelte documentation on await expressions](https://svelte.dev/docs/svelte/await-expressions).
### Svelte Attachments (Svelte 5.29+)
You can use attachments to add DOM behavior that runs on mount and cleans up on detach.
Example:
```ts
<scriptlang="ts">
import type { Attachment } from 'svelte/attachments';
### Use `vi.mocked`, not a generic `myFunctionMock`
@ -397,3 +563,91 @@ afterEach(() => {
vi.useRealTimers();
});
```
### Snapshots
Vitest snapshots are a powerful tool to ensure UI components and complex data structures do not change unexpectedly. They are particularly effective for catching regressions in rendered HTML or large objects without writing manual assertions for every property. When a snapshot detects a diff, you can update it using the `-u` param:
#### Updating Snapshots
When a test fails due to an intentional change, you can update the stored snapshots by appending the `-u` (or `--update`) flag to your test command.
#### 1. Standard Snapshots (External Files)
Use standard snapshots for large outputs like rendered HTML. These are stored in a separate **snapshots** directory.
##### Example: Testing Rendered HTML
```ts
test('multiple container connection should display a dropdown', async () => {
Inline snapshots are preferred for small data structures. They are written directly back into your test file, making the expected output easier to review during code sessions.
#### Example: Testing an Object
```ts
test('should parse targets with some special characters', async () => {
const info = await containerFileParser.parseContent(`
FROM busybox as base
ARG TARGETPLATFORM
RUN echo $TARGETPLATFORM > /plt
FROM --platform=\${TARGETPLATFORM} base AS base-target
**Result:** Vitest replaces the code in your .spec.ts file with the updated values:
```ts
expect(info).toMatchInlineSnapshot(`
{
"targets": [
"base",
"base-build",
],
}
`);
```
**Best Practices**
- **Review Before Committing:** Always inspect the diff of a snapshot update. It is easy to accidentally "fix" a test by updating a snapshot that actually contains a bug.
- **Keep Snapshots Focused:** Avoid snapshotting entire massive objects if you only care about one or two fields; use specific assertions instead to keep tests readable.
- **Use Inline for Small Data:** If the snapshot is less than 10 lines, prefer `toMatchInlineSnapshot()` for better visibility.
For more details, see the [Vitest snapshot guide](https://vitest.dev/guide/snapshot.html).
@ -252,6 +252,16 @@ This will create a binary according to your local system and output it to the `d
> **_macOS NOTE:_** On macOS the `dist/` folder will contain folders for `arm64` and `universal``.app` files. Ignore these and use the `.app` file in the `dist/mac/` folder for testing.
> **_macOS CODE SIGNING:_** When testing the compiled binary on macOS, you must ad-hoc sign the application before launching it. Without signing, macOS will terminate the app with a `Code Signature Invalid` error. Run the following command after compiling:
@ -450,10 +460,16 @@ Each sprint a new "Triage manager" will be assigned.
Your responsibilities include:
- Reviewing the [status/need-triage](https://github.com/podman-desktop/podman-desktop/issues?q=is%3Aopen+is%3Aissue+label%3Astatus%2Fneed-triage) label on new issues. As a maintainer, you will need to categorize these issues under the correct [area labels](https://github.com/podman-desktop/podman-desktop/labels?q=area%2F). Once categorized, remove the `status/need-triage` label and apply the appropriate area label.
- Evaluating the severity of new issues. If an issue is classified as "critical" or "high priority" and requires immediate attention, tag a maintainer in the issue and notify them via the public community channel.
- Identifying issues that are simple to resolve and marking them as "good first issue," thereby encouraging newcomers to contribute to the project.
- Evaluating any stale / lingering pull requests and pinging the respective contributors. If the pull request has been opened for an extensive amount of time, ping someone to contact the contributor / push any changes required to get it merged in. If there is no communication / the pull request is stale, close them.
- Review the [status/need-triage](https://github.com/podman-desktop/podman-desktop/issues?q=is%3Aopen+is%3Aissue+label%3Astatus%2Fneed-triage) label on new issues. As a maintainer, you will need to categorize these issues under the correct [domain labels](https://github.com/podman-desktop/podman-desktop/labels?q=domain%2F).
- Validate the issue type. Since issues can be opened without templates or may not align with the chosen template, ensure the issue is correctly classified and update labels accordingly. For example, an issue opened as a bug may actually be a feature request and should be relabeled to reflect the correct type.
- Add `dev/investigate` label if there is a need for the engineering team to take an initial look and provide some info on where the changes could be and categorize the issue in appropriate area. Add the issue to the current sprint.
- Add `qe/review` label if we want QE to reproduce this issue.
- Add `status/info-needed` label if logs are missing or additional info is needed from the user filing the issue
- Add `external-user` label if the issue is opened by someone outside the Podman Desktop organization maintainers.
- Identify issues that are simple to resolve and marking them as "good first issue," thereby encouraging newcomers to contribute to the project.
- Once categorized, remove the `status/need-triage` label.
- Evaluate the severity of new issues. If an issue is classified as "critical" or "high priority" and requires immediate attention, tag a maintainer in the issue and notify them via the public community channel.
- Evaluate any stale / lingering pull requests and pinging the respective contributors. If the pull request has been opened for an extensive amount of time, ping someone to contact the contributor / push any changes required to get it merged in. If there is no communication / the pull request is stale, close them.
[](https://insights.linuxfoundation.org/project/podman-desktop)
We’d love to hear how you’re using (or planning to use) Podman Desktop. Spend **30 minutes** chatting with us about your use case, and we’ll send you some Podman Desktop swag as a thank-you!
Check out the [list of companies](./ADOPTERS.md) already using Podman Desktop.
👉 Please complete this [form](https://forms.gle/mTagLs36275B4L198), and we’ll be in touch to arrange a time.
Check out the growing [list of companies](./ADOPTERS.md) already using Podman Desktop, and add your organization to be part of the community of adopters.
Your feedback is invaluable and will play a direct role in guiding the evolution of Podman Desktop. We greatly appreciate your time and perspective.
## Code of Conduct
@ -142,7 +149,7 @@ This project uses the [Containers Community Code of Conduct](https://github.com/
## Testing
[](https://app.argos-ci.com/containers/podman-desktop/reference)
[](https://app.argos-ci.com/containers/podman-desktop-website)
@ -57,11 +57,18 @@ The release may be tested using the assets generated within the pre-release.
**Cherry picking:**
If there are fixes that need to be made to the release as brought up by QE the following steps need to be completed:
If there are fixes that need to be made to the release as brought up by QE the following steps need to be completed (using hypothetical release 0.12.0 as an example):
1. Create a branch **FROM THE RELEASE**. Example, 0.12.x of release 0.12.0. **IMPORTANT NOTE:** Literally `0.12.x` not `0.12.1`.
2. Create PR(s) with the fixes that merge into the main branch and use mergify.io to open a backport PR(s) to the 0.12.x branch by adding the following comment in the main PR(s): `@Mergifyio backport 0.12.x`
3. Make sure all PR's are merged
1. Create the cherry-fix branch `0.12.x` from tag `0.12.0`:
```sh
$ git fetch --tags
$ git checkout -b 0.12.x v0.12.0
$ git push origin 0.12.x
```
2. Create PRs with the fixes that merge into `main` and use Mergify to open backport PRs to `0.12.x` by adding the following comment in the main PRs: `@Mergifyio backport 0.12.x`
3. Make sure all PRs are merged, before re-spinning a release.
## Security and Disclosure Information Policy for the Podman Desktop Project
# Security and Disclosure Information Policy for the Podman Desktop Project
The Podman Desktop Project follows the [Security and Disclosure Information Policy](https://github.com/containers/common/blob/main/SECURITY.md) for the Containers Projects.
This is the security policy for the Podman Desktop project. It applies to all repositories
in the [Podman Desktop GitHub organization](https://github.com/podman-desktop).
- [Reporting a Vulnerability](#Reporting-a-Vulnerability)
This is a private mailing list for the core maintainers.
## Security Announcements
The [cncf-podman-desktop-maintainers@lists.cncf.io](mailto:cncf-podman-desktop-maintainers@lists.cncf.io) email
list is used for messages about Podman Desktop security announcements as well as general announcements and discussions.
You can join the list [here](https://lists.cncf.io/g/cncf-podman-desktop-maintainers/join)
or by sending an email to [cncf-podman-desktop-maintainers+subscribe@lists.cncf.io](mailto:cncf-podman-desktop-maintainers+subscribe@lists.cncf.io?subject=subscribe).
## Security Vulnerability Response
Each report is acknowledged and analyzed by the core maintainers within 3 working days.
Any vulnerability information shared with core maintainers stays within a Podman Desktop project
and will not be disseminated to other projects unless it is necessary to get the issue fixed.
As the security issue moves from triage, to an identified fix, to release planning, the core
"value":"Unable to retrieve the latest Compose version. This may be caused by a GitHub API rate limit or a network issue.\n\nPlease try again later or check your network connection."
test('updateConfigAndContextComposeBinary: should set isPodmanComposeInstalledSystemWide context to false when podman-compose is not installed',async()=>{
test('updateConfigAndContextComposeBinary: should set isPodmanComposeInstalledSystemWide context to false when podman-compose is not installed',async()=>{