@@ -35,31 +35,101 @@ export const ContainerService = {
3535
3636 async run ( container : Container ) : Promise < boolean > {
3737 try {
38- const stream = await container . attach ( {
39- stream : true ,
40- stdout : true ,
41- stderr : true
42- } )
38+ // Start the container
39+ await container . start ( )
40+ core . info ( `Started container ${ container . id } ` )
41+
42+ // Check if this is a dependabot container (has the expected structure)
43+ const containerInfo = await container . inspect ( )
44+ const isDependabotContainer = containerInfo . Config ?. Env ?. some ( env =>
45+ env . startsWith ( 'DEPENDABOT_JOB_ID=' )
46+ )
47+
48+ if ( isDependabotContainer ) {
49+ // For dependabot containers, run CA certificates update as root first
50+ await this . execCommand (
51+ container ,
52+ [ '/usr/sbin/update-ca-certificates' ] ,
53+ 'root'
54+ )
55+
56+ // Then run the dependabot commands as dependabot user
57+ const dependabotCommands = [
58+ 'mkdir -p /home/dependabot/dependabot-updater/output' ,
59+ '$DEPENDABOT_HOME/dependabot-updater/bin/run fetch_files' ,
60+ '$DEPENDABOT_HOME/dependabot-updater/bin/run update_files'
61+ ]
62+
63+ for ( const cmd of dependabotCommands ) {
64+ await this . execCommand (
65+ container ,
66+ [ '/bin/sh' , '-c' , cmd ] ,
67+ 'dependabot'
68+ )
69+ }
70+ } else {
71+ // For test containers and other containers, just wait for completion
72+ const outcome = await container . wait ( )
73+ if ( outcome . StatusCode !== 0 ) {
74+ throw new Error ( `Container exited with code ${ outcome . StatusCode } ` )
75+ }
76+ }
77+
78+ return true
79+ } catch ( error ) {
80+ core . info ( `Failure running container ${ container . id } : ${ error } ` )
81+ throw new ContainerRuntimeError (
82+ 'The updater encountered one or more errors.'
83+ )
84+ } finally {
85+ try {
86+ await container . remove ( { v : true , force : true } )
87+ core . info ( `Cleaned up container ${ container . id } ` )
88+ } catch ( error ) {
89+ core . info ( `Failed to clean up container ${ container . id } : ${ error } ` )
90+ }
91+ }
92+ } ,
93+
94+ async execCommand (
95+ container : Container ,
96+ cmd : string [ ] ,
97+ user : string
98+ ) : Promise < void > {
99+ const exec = await container . exec ( {
100+ Cmd : cmd ,
101+ User : user ,
102+ AttachStdout : true ,
103+ AttachStderr : true
104+ } )
105+
106+ const stream = await exec . start ( { } )
107+
108+ // Wait for the stream to end
109+ await new Promise < void > ( ( resolve , reject ) => {
43110 container . modem . demuxStream (
44111 stream ,
45112 outStream ( 'updater' ) ,
46113 errStream ( 'updater' )
47114 )
48115
49- await container . start ( )
50- const outcome = await container . wait ( )
116+ stream . on ( 'end' , ( ) => {
117+ resolve ( )
118+ } )
51119
52- if ( outcome . StatusCode === 0 ) {
53- return true
54- } else {
55- core . info ( `Failure running container ${ container . id } ` )
56- throw new ContainerRuntimeError (
57- 'The updater encountered one or more errors.'
58- )
59- }
60- } finally {
61- await container . remove ( { v : true } )
62- core . info ( `Cleaned up container ${ container . id } ` )
120+ stream . on ( 'error' , error => {
121+ reject ( error )
122+ } )
123+ } )
124+
125+ // Wait a bit for the exec to complete properly
126+ await new Promise ( resolve => setTimeout ( resolve , 100 ) )
127+
128+ const inspection = await exec . inspect ( )
129+ if ( inspection . ExitCode !== 0 ) {
130+ throw new Error (
131+ `Command failed with exit code ${ inspection . ExitCode } : ${ cmd . join ( ' ' ) } `
132+ )
63133 }
64134 }
65135}
0 commit comments