This commit is contained in:
jarek
2026-04-03 18:32:46 +02:00
parent 2027c9d44c
commit 7f26c0a585
5 changed files with 24 additions and 7 deletions
+1 -1
View File
@@ -1 +1 @@
v1.0.23
v1.0.24
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "dockhand",
"private": true,
"version": "1.0.23",
"version": "1.0.24",
"type": "module",
"scripts": {
"dev": "npx vite dev",
+9
View File
@@ -1,4 +1,13 @@
[
{
"version": "1.0.24",
"date": "2026-04-03",
"changes": [
{ "type": "fix", "text": "browsing HTTP registries fails with SSL error (#868)" },
{ "type": "fix", "text": "git stack deploy options (build, re-pull, force redeploy) not persisted in edit dialog" }
],
"imageTag": "fnsys/dockhand:v1.0.24"
},
{
"version": "1.0.23",
"date": "2026-04-03",
+6
View File
@@ -2091,6 +2091,9 @@ export async function getGitStacks(environmentId?: number): Promise<GitStackWith
autoUpdateCron: gitStacks.autoUpdateCron,
webhookEnabled: gitStacks.webhookEnabled,
webhookSecret: gitStacks.webhookSecret,
buildOnDeploy: gitStacks.buildOnDeploy,
repullImages: gitStacks.repullImages,
forceRedeploy: gitStacks.forceRedeploy,
lastSync: gitStacks.lastSync,
lastCommit: gitStacks.lastCommit,
syncStatus: gitStacks.syncStatus,
@@ -2119,6 +2122,9 @@ export async function getGitStacks(environmentId?: number): Promise<GitStackWith
autoUpdateCron: gitStacks.autoUpdateCron,
webhookEnabled: gitStacks.webhookEnabled,
webhookSecret: gitStacks.webhookSecret,
buildOnDeploy: gitStacks.buildOnDeploy,
repullImages: gitStacks.repullImages,
forceRedeploy: gitStacks.forceRedeploy,
lastSync: gitStacks.lastSync,
lastCommit: gitStacks.lastCommit,
syncStatus: gitStacks.syncStatus,
+7 -5
View File
@@ -2625,7 +2625,9 @@ function parseImageReference(imageName: string): { registry: string; repo: strin
* 'ghcr.io' -> { host: 'ghcr.io', path: '', fullRegistry: 'ghcr.io' }
* 'registry.example.com:5000/myorg' -> { host: 'registry.example.com:5000', path: '/myorg', fullRegistry: 'registry.example.com:5000/myorg' }
*/
export function parseRegistryUrl(url: string): { host: string; path: string; fullRegistry: string } {
export function parseRegistryUrl(url: string): { host: string; path: string; fullRegistry: string; protocol: string } {
// Detect protocol (default to https)
const protocol = url.startsWith('http://') ? 'http' : 'https';
// Remove protocol
const withoutProtocol = url.replace(/^https?:\/\//, '');
// Remove trailing slash
@@ -2633,11 +2635,11 @@ export function parseRegistryUrl(url: string): { host: string; path: string; ful
// Split on first slash (after port if present)
const slashIndex = trimmed.indexOf('/');
if (slashIndex === -1) {
return { host: trimmed, path: '', fullRegistry: trimmed };
return { host: trimmed, path: '', fullRegistry: trimmed, protocol };
}
const host = trimmed.substring(0, slashIndex);
const path = trimmed.substring(slashIndex); // includes leading /
return { host, path, fullRegistry: trimmed };
return { host, path, fullRegistry: trimmed, protocol };
}
/**
@@ -2822,7 +2824,7 @@ export async function getRegistryAuthHeader(
try {
// Parse URL to extract host (V2 API is always at the host root)
const parsed = parseRegistryUrl(registryUrl);
const apiBaseUrl = `https://${parsed.host}`;
const apiBaseUrl = `${parsed.protocol}://${parsed.host}`;
// Step 1: Challenge request to /v2/ (always at registry root, not under org path)
const challengeResponse = await fetch(`${apiBaseUrl}/v2/`, {
@@ -2931,7 +2933,7 @@ export async function getRegistryAuth(
const parsed = parseRegistryUrl(registry.url);
// V2 API endpoints are always at the registry host root
const baseUrl = `https://${parsed.host}`;
const baseUrl = `${parsed.protocol}://${parsed.host}`;
// Get auth header using proper token flow
const credentials = registry.username && registry.password