Skip to content

Commit 024ecea

Browse files
committed
fix(ci): restore check workflow stability
1 parent 8e7f191 commit 024ecea

6 files changed

Lines changed: 203 additions & 105 deletions

File tree

.github/actions/setup/action.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ runs:
2121
uses: actions/setup-node@v6
2222
with:
2323
node-version: ${{ inputs.node-version }}
24+
- name: Install OpenSSH client
25+
shell: bash
26+
run: |
27+
sudo apt-get update
28+
sudo apt-get install -y openssh-client
2429
- name: Install node-gyp
2530
shell: bash
2631
run: npm install -g node-gyp

bun.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/api/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ ENV PATH=/opt/bun/bin:$PATH
1010
WORKDIR /workspace
1111

1212
RUN apt-get update && apt-get install -y --no-install-recommends \
13-
ca-certificates curl git docker.io docker-compose-v2 sshpass python3 make g++ unzip \
13+
ca-certificates curl git docker.io docker-compose-v2 openssh-client sshpass python3 make g++ unzip \
1414
&& rm -rf /var/lib/apt/lists/*
1515

1616
RUN curl -fsSL https://deb.nodesource.com/setup_24.x | bash - \

packages/app/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@
7373
"@effect/sql": "^0.51.0",
7474
"@effect/typeclass": "^0.40.0",
7575
"@effect/workflow": "^0.18.0",
76-
"@gridland/bun": "^0.2.53",
77-
"@gridland/web": "^0.2.53",
76+
"@gridland/bun": "0.2.53",
77+
"@gridland/web": "0.2.53",
7878
"effect": "^3.21.0",
7979
"react": "^19.2.4",
8080
"react-dom": "^19.2.4",

packages/app/src/docker-git/api-project-codec.ts

Lines changed: 55 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,21 @@ export type ApiProjectDetails = ApiProjectSummary & {
3030
}
3131

3232
type ProjectDetailFields = Omit<ApiProjectDetails, keyof ApiProjectSummary>
33+
type RawProjectDetailFields = {
34+
readonly containerName: string | null
35+
readonly serviceName: string | null
36+
readonly sshUser: string | null
37+
readonly sshPort: number | null
38+
readonly targetDir: string | null
39+
readonly projectDir: string | null
40+
readonly sshCommand: string | null
41+
readonly authorizedKeysPath: string | null
42+
readonly authorizedKeysExists: boolean | null
43+
readonly envGlobalPath: string | null
44+
readonly envProjectPath: string | null
45+
readonly codexAuthPath: string | null
46+
readonly codexHome: string | null
47+
}
3348

3449
const isProjectStatus = (
3550
value: string
@@ -38,8 +53,7 @@ const isProjectStatus = (
3853
const stringOrEmpty = (value: string | null): string => value ?? ""
3954

4055
const numberOrZero = (value: number | null): number => value ?? 0
41-
const readNullableNumber = (value: JsonValue | undefined): number | null =>
42-
typeof value === "number" ? value : value === null ? null : null
56+
const readNullableNumber = (value: JsonValue | undefined): number | null => typeof value === "number" ? value : null
4357

4458
const readSummaryBaseFields = (
4559
object: ReturnType<typeof asObject>
@@ -78,46 +92,53 @@ const readSummaryBaseFields = (
7892

7993
const readRequiredProjectDetails = (
8094
object: ReturnType<typeof asObject>
81-
): ProjectDetailFields | null => {
95+
): RawProjectDetailFields | null => {
8296
if (object === null) {
8397
return null
8498
}
8599

86-
const containerName = asString(object["containerName"])
87-
const serviceName = asString(object["serviceName"])
88-
const sshUser = asString(object["sshUser"])
89-
const sshPort = typeof object["sshPort"] === "number" ? object["sshPort"] : null
90-
const targetDir = asString(object["targetDir"])
91-
const projectDir = asString(object["projectDir"])
92-
const sshCommand = asString(object["sshCommand"])
93-
const authorizedKeysPath = asString(object["authorizedKeysPath"])
94-
const authorizedKeysExists = typeof object["authorizedKeysExists"] === "boolean"
95-
? object["authorizedKeysExists"]
96-
: null
97-
const envGlobalPath = asString(object["envGlobalPath"])
98-
const envProjectPath = asString(object["envProjectPath"])
99-
const codexAuthPath = asString(object["codexAuthPath"])
100-
const codexHome = asString(object["codexHome"])
101-
const values = [containerName, serviceName, sshUser, sshPort, targetDir, projectDir, sshCommand, authorizedKeysPath, authorizedKeysExists, envGlobalPath, envProjectPath, codexAuthPath, codexHome]
100+
return {
101+
containerName: asString(object["containerName"]),
102+
serviceName: asString(object["serviceName"]),
103+
sshUser: asString(object["sshUser"]),
104+
sshPort: typeof object["sshPort"] === "number" ? object["sshPort"] : null,
105+
targetDir: asString(object["targetDir"]),
106+
projectDir: asString(object["projectDir"]),
107+
sshCommand: asString(object["sshCommand"]),
108+
authorizedKeysPath: asString(object["authorizedKeysPath"]),
109+
authorizedKeysExists: typeof object["authorizedKeysExists"] === "boolean"
110+
? object["authorizedKeysExists"]
111+
: null,
112+
envGlobalPath: asString(object["envGlobalPath"]),
113+
envProjectPath: asString(object["envProjectPath"]),
114+
codexAuthPath: asString(object["codexAuthPath"]),
115+
codexHome: asString(object["codexHome"])
116+
}
117+
}
102118

103-
if (values.includes(null)) {
119+
const decodeRequiredProjectDetails = (
120+
object: ReturnType<typeof asObject>
121+
): ProjectDetailFields | null => {
122+
const rawFields = readRequiredProjectDetails(object)
123+
124+
if (rawFields === null || Object.values(rawFields).includes(null)) {
104125
return null
105126
}
106127

107128
return {
108-
containerName: stringOrEmpty(containerName),
109-
serviceName: stringOrEmpty(serviceName),
110-
sshUser: stringOrEmpty(sshUser),
111-
sshPort: numberOrZero(sshPort),
112-
targetDir: stringOrEmpty(targetDir),
113-
projectDir: stringOrEmpty(projectDir),
114-
sshCommand: stringOrEmpty(sshCommand),
115-
authorizedKeysPath: stringOrEmpty(authorizedKeysPath),
116-
authorizedKeysExists: authorizedKeysExists === true,
117-
envGlobalPath: stringOrEmpty(envGlobalPath),
118-
envProjectPath: stringOrEmpty(envProjectPath),
119-
codexAuthPath: stringOrEmpty(codexAuthPath),
120-
codexHome: stringOrEmpty(codexHome)
129+
containerName: stringOrEmpty(rawFields.containerName),
130+
serviceName: stringOrEmpty(rawFields.serviceName),
131+
sshUser: stringOrEmpty(rawFields.sshUser),
132+
sshPort: numberOrZero(rawFields.sshPort),
133+
targetDir: stringOrEmpty(rawFields.targetDir),
134+
projectDir: stringOrEmpty(rawFields.projectDir),
135+
sshCommand: stringOrEmpty(rawFields.sshCommand),
136+
authorizedKeysPath: stringOrEmpty(rawFields.authorizedKeysPath),
137+
authorizedKeysExists: rawFields.authorizedKeysExists === true,
138+
envGlobalPath: stringOrEmpty(rawFields.envGlobalPath),
139+
envProjectPath: stringOrEmpty(rawFields.envProjectPath),
140+
codexAuthPath: stringOrEmpty(rawFields.codexAuthPath),
141+
codexHome: stringOrEmpty(rawFields.codexHome)
121142
}
122143
}
123144

@@ -134,7 +155,7 @@ const readProjectSummaryFields = (value: JsonValue): ApiProjectSummary | null =>
134155
}
135156

136157
const readProjectDetailFields = (value: JsonValue): ProjectDetailFields | null =>
137-
readRequiredProjectDetails(asObject(value))
158+
decodeRequiredProjectDetails(asObject(value))
138159

139160
export const decodeProjectSummary = (value: JsonValue): ApiProjectSummary | null => readProjectSummaryFields(value)
140161

0 commit comments

Comments
 (0)