From b86c42b368574f2ca1fc9338ec8b1e8b88847c0d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 1 Jul 2026 18:28:59 +0000 Subject: [PATCH 1/3] Initial plan From 02da098dd0ad53e5c9586ea67a32cada4665c792 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 1 Jul 2026 18:34:18 +0000 Subject: [PATCH 2/3] feat: add container.mounts to AWF config file schema --- docs/awf-config.schema.json | 8 ++++++++ src/awf-config-schema.json | 8 ++++++++ src/config-file-mapping.test.ts | 21 +++++++++++++++++++++ src/config-file.ts | 1 + src/config-mapper.ts | 1 + src/schema.test.ts | 12 ++++++++++++ 6 files changed, 51 insertions(+) diff --git a/docs/awf-config.schema.json b/docs/awf-config.schema.json index c80c75d90..6339ac5ab 100644 --- a/docs/awf-config.schema.json +++ b/docs/awf-config.schema.json @@ -607,6 +607,14 @@ "runnerToolCachePath": { "type": "string", "description": "Host runner tool cache directory to mount read-only into chroot mode. When set, AWF checks this path first before environment-based auto-detection." + }, + "mounts": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[^:]+:[^:]+(:(ro|rw))?$" + }, + "description": "Custom volume mounts for the agent container. Format: \"host_path:container_path[:ro|rw]\". In chroot mode, container paths are automatically prefixed with /host." } } }, diff --git a/src/awf-config-schema.json b/src/awf-config-schema.json index c80c75d90..6339ac5ab 100644 --- a/src/awf-config-schema.json +++ b/src/awf-config-schema.json @@ -607,6 +607,14 @@ "runnerToolCachePath": { "type": "string", "description": "Host runner tool cache directory to mount read-only into chroot mode. When set, AWF checks this path first before environment-based auto-detection." + }, + "mounts": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[^:]+:[^:]+(:(ro|rw))?$" + }, + "description": "Custom volume mounts for the agent container. Format: \"host_path:container_path[:ro|rw]\". In chroot mode, container paths are automatically prefixed with /host." } } }, diff --git a/src/config-file-mapping.test.ts b/src/config-file-mapping.test.ts index 56c19f427..5215833dc 100644 --- a/src/config-file-mapping.test.ts +++ b/src/config-file-mapping.test.ts @@ -299,6 +299,27 @@ describe('mapAwfFileConfigToCliOptions', () => { expect(result.runnerToolCachePath).toBe('/opt/hostedtoolcache'); }); + it('maps container.mounts to mount array', () => { + const result = mapAwfFileConfigToCliOptions({ + container: { + mounts: [ + '/tmp/gh-aw:/tmp/gh-aw:ro', + '/tmp/gh-aw/home:/tmp/gh-aw/home:rw', + ], + }, + }); + + expect(result.mount).toEqual([ + '/tmp/gh-aw:/tmp/gh-aw:ro', + '/tmp/gh-aw/home:/tmp/gh-aw/home:rw', + ]); + }); + + it('leaves mount undefined when container.mounts is not set', () => { + const result = mapAwfFileConfigToCliOptions({ container: {} }); + expect(result.mount).toBeUndefined(); + }); + it('maps environment fields', () => { const result = mapAwfFileConfigToCliOptions({ environment: { diff --git a/src/config-file.ts b/src/config-file.ts index 7e842b0b0..630b927ae 100644 --- a/src/config-file.ts +++ b/src/config-file.ts @@ -112,6 +112,7 @@ export interface AwfFileConfig { dockerHost?: string; dockerHostPathPrefix?: string; runnerToolCachePath?: string; + mounts?: string[]; }; chroot?: { binariesSourcePath?: string; diff --git a/src/config-mapper.ts b/src/config-mapper.ts index 677741f67..e521fd38f 100644 --- a/src/config-mapper.ts +++ b/src/config-mapper.ts @@ -104,6 +104,7 @@ export function mapAwfFileConfigToCliOptions(config: AwfFileConfig): Record { expect(validate({ container: { runnerToolCachePath: 123 } })).toBe(false); }); + it('accepts valid container.mounts array', () => { + expect(validate({ container: { mounts: ['/tmp/gh-aw:/tmp/gh-aw:ro'] } })).toBe(true); + expect(validate({ container: { mounts: ['/tmp/gh-aw:/tmp/gh-aw:rw', '/data:/data'] } })).toBe(true); + expect(validate({ container: { mounts: [] } })).toBe(true); + }); + + it('rejects invalid container.mounts entries', () => { + expect(validate({ container: { mounts: ['invalid-no-colon'] } })).toBe(false); + expect(validate({ container: { mounts: ['/src:/dst:invalid-mode'] } })).toBe(false); + expect(validate({ container: { mounts: 'not-an-array' } })).toBe(false); + }); + it('accepts runner.topology and runner.sysrootImage', () => { expect(validate({ runner: { topology: 'arc-dind' } })).toBe(true); expect(validate({ runner: { topology: 'invalid' } })).toBe(false); From b7b23f77a7475bcd11f2b5c7a89a009c3787c6a1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 1 Jul 2026 19:18:29 +0000 Subject: [PATCH 3/3] fix: tighten container.mounts schema pattern to require absolute paths --- docs/awf-config.schema.json | 4 ++-- src/awf-config-schema.json | 4 ++-- src/schema.test.ts | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/awf-config.schema.json b/docs/awf-config.schema.json index 6339ac5ab..702bbc9a6 100644 --- a/docs/awf-config.schema.json +++ b/docs/awf-config.schema.json @@ -612,9 +612,9 @@ "type": "array", "items": { "type": "string", - "pattern": "^[^:]+:[^:]+(:(ro|rw))?$" + "pattern": "^/[^:]+:/[^:]+(:(ro|rw))?$" }, - "description": "Custom volume mounts for the agent container. Format: \"host_path:container_path[:ro|rw]\". In chroot mode, container paths are automatically prefixed with /host." + "description": "Custom volume mounts for the agent container. Format: \"/host_path:/container_path[:ro|rw]\" (both paths must be absolute). In chroot mode, container paths are automatically prefixed with /host." } } }, diff --git a/src/awf-config-schema.json b/src/awf-config-schema.json index 6339ac5ab..702bbc9a6 100644 --- a/src/awf-config-schema.json +++ b/src/awf-config-schema.json @@ -612,9 +612,9 @@ "type": "array", "items": { "type": "string", - "pattern": "^[^:]+:[^:]+(:(ro|rw))?$" + "pattern": "^/[^:]+:/[^:]+(:(ro|rw))?$" }, - "description": "Custom volume mounts for the agent container. Format: \"host_path:container_path[:ro|rw]\". In chroot mode, container paths are automatically prefixed with /host." + "description": "Custom volume mounts for the agent container. Format: \"/host_path:/container_path[:ro|rw]\" (both paths must be absolute). In chroot mode, container paths are automatically prefixed with /host." } } }, diff --git a/src/schema.test.ts b/src/schema.test.ts index f26964a19..31987ca53 100644 --- a/src/schema.test.ts +++ b/src/schema.test.ts @@ -254,6 +254,10 @@ describe('awf-config.schema.json', () => { expect(validate({ container: { mounts: ['invalid-no-colon'] } })).toBe(false); expect(validate({ container: { mounts: ['/src:/dst:invalid-mode'] } })).toBe(false); expect(validate({ container: { mounts: 'not-an-array' } })).toBe(false); + // Relative paths must be rejected (runtime validator requires absolute paths) + expect(validate({ container: { mounts: ['relative/path:/container/dst'] } })).toBe(false); + expect(validate({ container: { mounts: ['/host/src:relative/container'] } })).toBe(false); + expect(validate({ container: { mounts: ['./relative:/container/dst:ro'] } })).toBe(false); }); it('accepts runner.topology and runner.sysrootImage', () => {