Skip to content

Commit ceddbfe

Browse files
committed
installer: harden tmp cleanup, systemd checks, 0.0.0.0 bind defaults
1 parent 5815236 commit ceddbfe

7 files changed

Lines changed: 193 additions & 39 deletions

File tree

.github/workflows/code-review.yml

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,24 @@ on:
66
- opened
77
- synchronize
88
- reopened
9+
workflow_dispatch:
10+
inputs:
11+
base_sha:
12+
description: "Base commit SHA (optional)"
13+
required: false
14+
type: string
15+
head_sha:
16+
description: "Head commit SHA (optional)"
17+
required: false
18+
type: string
19+
pr_number:
20+
description: "PR number to post review comment (optional)"
21+
required: false
22+
type: string
23+
pr_title:
24+
description: "PR title override for review prompt (optional)"
25+
required: false
26+
type: string
927
issue_comment:
1028
types:
1129
- created
@@ -22,19 +40,52 @@ permissions:
2240
jobs:
2341
codereview:
2442
runs-on: ubuntu-latest
25-
if: ${{ github.event_name == 'pull_request' && secrets.CODEXSESS_URL != '' && secrets.CODEXSESS_API_KEY != '' }}
43+
if: ${{ (github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') && secrets.CODEXSESS_URL != '' && secrets.CODEXSESS_API_KEY != '' }}
2644
steps:
2745
- name: Checkout
2846
uses: actions/checkout@v6
2947
with:
3048
fetch-depth: 0
3149

50+
- name: Resolve review context
51+
id: ctx
52+
run: |
53+
set -euo pipefail
54+
EVENT="${{ github.event_name }}"
55+
56+
if [ "$EVENT" = "pull_request" ]; then
57+
BASE_SHA="${{ github.event.pull_request.base.sha }}"
58+
HEAD_SHA="${{ github.event.pull_request.head.sha }}"
59+
PR_NUMBER="${{ github.event.pull_request.number }}"
60+
PR_TITLE="${{ github.event.pull_request.title }}"
61+
else
62+
BASE_SHA="${{ github.event.inputs.base_sha }}"
63+
HEAD_SHA="${{ github.event.inputs.head_sha }}"
64+
PR_NUMBER="${{ github.event.inputs.pr_number }}"
65+
PR_TITLE="${{ github.event.inputs.pr_title }}"
66+
fi
67+
68+
if [ -z "$HEAD_SHA" ]; then
69+
HEAD_SHA="$(git rev-parse HEAD)"
70+
fi
71+
if [ -z "$BASE_SHA" ]; then
72+
BASE_SHA="$(git rev-parse "${HEAD_SHA}~1")"
73+
fi
74+
if [ -z "$PR_TITLE" ]; then
75+
PR_TITLE="Manual code review ${BASE_SHA}...${HEAD_SHA}"
76+
fi
77+
78+
echo "base_sha=$BASE_SHA" >> "$GITHUB_OUTPUT"
79+
echo "head_sha=$HEAD_SHA" >> "$GITHUB_OUTPUT"
80+
echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
81+
echo "pr_title=$PR_TITLE" >> "$GITHUB_OUTPUT"
82+
3283
- name: Build PR diff
3384
id: diff
3485
run: |
3586
set -euo pipefail
36-
BASE_SHA="${{ github.event.pull_request.base.sha }}"
37-
HEAD_SHA="${{ github.event.pull_request.head.sha }}"
87+
BASE_SHA="${{ steps.ctx.outputs.base_sha }}"
88+
HEAD_SHA="${{ steps.ctx.outputs.head_sha }}"
3889
mkdir -p review_chunks review_out
3990
git diff --name-status "${BASE_SHA}...${HEAD_SHA}" > review_out/files.txt || true
4091
mapfile -t CHANGED_FILES < <(git diff --name-only "${BASE_SHA}...${HEAD_SHA}")
@@ -72,7 +123,7 @@ jobs:
72123
[ -f "review_chunks/${idx}.diff" ] || continue
73124
BODY=$(jq -n \
74125
--rawfile diff "review_chunks/${idx}.diff" \
75-
--arg title "${{ github.event.pull_request.title }}" \
126+
--arg title "${{ steps.ctx.outputs.pr_title }}" \
76127
--arg file "$file" \
77128
'{
78129
model: "gpt-5.2-codex",
@@ -110,7 +161,7 @@ jobs:
110161
BODY=$(jq -n \
111162
--rawfile files review_out/files.txt \
112163
--rawfile chunk_reviews review_out/chunk_reviews.md \
113-
--arg title "${{ github.event.pull_request.title }}" \
164+
--arg title "${{ steps.ctx.outputs.pr_title }}" \
114165
'{
115166
model: "gpt-5.2-codex",
116167
language: "mixed",
@@ -132,14 +183,14 @@ jobs:
132183
jq -r '.review // "No review output returned."' review_out/final.json > review.txt
133184
134185
- name: Upsert PR comment
135-
if: steps.diff.outputs.has_diff == 'true'
186+
if: steps.diff.outputs.has_diff == 'true' && steps.ctx.outputs.pr_number != ''
136187
uses: actions/github-script@v8
137188
with:
138189
script: |
139190
const fs = require('fs');
140191
const owner = context.repo.owner;
141192
const repo = context.repo.repo;
142-
const issue_number = context.payload.pull_request.number;
193+
const issue_number = Number('${{ steps.ctx.outputs.pr_number }}');
143194
const marker = '<!-- codexsess-code-review -->';
144195
let review = 'No review output returned.';
145196
try {
@@ -297,7 +348,7 @@ jobs:
297348
298349
- name: Upload patch artifact
299350
if: steps.diff.outputs.has_diff == 'true' && steps.validate.outputs.valid == 'true'
300-
uses: actions/upload-artifact@v4
351+
uses: actions/upload-artifact@v7
301352
with:
302353
name: codexsess-autofix-patch-pr-${{ steps.pr.outputs.number }}
303354
path: autofix.patch

.github/workflows/release.yml

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ jobs:
148148
sha256sum packages/*.deb packages/*.rpm >> SHA256SUMS.txt
149149
150150
- name: Upload artifacts
151-
uses: actions/upload-artifact@v4
151+
uses: actions/upload-artifact@v7
152152
with:
153153
name: codexsess-build-${{ github.run_number }}
154154
path: |
@@ -187,29 +187,33 @@ jobs:
187187
echo "has_changelog=false" >> "$GITHUB_OUTPUT"
188188
fi
189189
190-
- name: Upload to release (with changelog)
191-
if: startsWith(github.ref, 'refs/tags/v') && steps.changelog.outputs.has_changelog == 'true'
192-
uses: softprops/action-gh-release@v2
193-
with:
194-
body_path: dist/release-notes.md
195-
files: |
190+
- name: Publish release assets
191+
if: startsWith(github.ref, 'refs/tags/v')
192+
env:
193+
GH_TOKEN: ${{ github.token }}
194+
run: |
195+
set -euo pipefail
196+
TAG="${GITHUB_REF_NAME}"
197+
ASSETS=(
196198
dist/codexsess-linux-amd64
197199
dist/codexsess-linux-arm64
198200
dist/codexsess-windows-amd64.exe
199201
dist/codexsess-windows-arm64.exe
200202
dist/SHA256SUMS.txt
201203
dist/packages/*.deb
202204
dist/packages/*.rpm
205+
)
206+
207+
if gh release view "$TAG" >/dev/null 2>&1; then
208+
if [ "${{ steps.changelog.outputs.has_changelog }}" = "true" ]; then
209+
gh release edit "$TAG" --notes-file dist/release-notes.md
210+
fi
211+
gh release upload "$TAG" "${ASSETS[@]}" --clobber
212+
exit 0
213+
fi
203214
204-
- name: Upload to release (default)
205-
if: startsWith(github.ref, 'refs/tags/v') && steps.changelog.outputs.has_changelog != 'true'
206-
uses: softprops/action-gh-release@v2
207-
with:
208-
files: |
209-
dist/codexsess-linux-amd64
210-
dist/codexsess-linux-arm64
211-
dist/codexsess-windows-amd64.exe
212-
dist/codexsess-windows-arm64.exe
213-
dist/SHA256SUMS.txt
214-
dist/packages/*.deb
215-
dist/packages/*.rpm
215+
if [ "${{ steps.changelog.outputs.has_changelog }}" = "true" ]; then
216+
gh release create "$TAG" "${ASSETS[@]}" --notes-file dist/release-notes.md
217+
else
218+
gh release create "$TAG" "${ASSETS[@]}" --title "$TAG"
219+
fi

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ The format follows Keep a Changelog and uses semantic version tags (`vMAJOR.MINO
1515
- API/code-review integration and logging coverage were refined so review calls are visible and traceable in API logs.
1616
- Settings and documentation were expanded with code-review endpoint usage details and cURL examples.
1717
- GitHub Actions code-review and autofix automation are now consolidated into a single workflow file for simpler maintenance.
18+
- GitHub code-review workflow now supports manual run from Actions (`workflow_dispatch`) with optional base/head SHA and PR comment target.
19+
- Release and code-review workflows now use Node 24-ready artifact action (`actions/upload-artifact@v7`), and release publishing was migrated from `softprops/action-gh-release` to `gh release` CLI.
20+
- Fixed Linux installer cleanup trap to avoid `bash: line 1: tmp: unbound variable` after package install in strict shell mode (`set -u`).
21+
- Installer now prints default auth credentials (`admin / hijilabs`) and password change command (`codexsess --changepassword`) after install.
22+
- Server-mode installer now verifies `codexsess.service` active state and prints status check command (`systemctl status codexsess`).
23+
- Default bind address is now `0.0.0.0:<PORT>` (with `CODEXSESS_BIND_ADDR` override support), and server service unit sets `CODEXSESS_BIND_ADDR=0.0.0.0:3061`.
24+
- Installer terminal output now uses clearer colored status lines for info, success, and error messages.
25+
- README now documents `CODEXSESS_BIND_ADDR` and includes GUI-mode `~/.bashrc` bind override example for `0.0.0.0`.
1826

1927
## [1.0.1] - 2026-03-18
2028

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@ GitHub Actions example (PR diff):
162162
163163
| Variable | Default | Example | Description |
164164
|---|---|---|---|
165-
| `PORT` | `3061` | `PORT=8080` | HTTP server port. Bind address is `127.0.0.1:<PORT>`. |
165+
| `PORT` | `3061` | `PORT=8080` | HTTP server port used when `CODEXSESS_BIND_ADDR` is not explicitly set. |
166+
| `CODEXSESS_BIND_ADDR` | `0.0.0.0:<PORT>` | `CODEXSESS_BIND_ADDR=0.0.0.0:3061` | Full bind address override (`host:port`) for HTTP server. |
166167
| `CODEXSESS_NO_OPEN_BROWSER` | `false` | `CODEXSESS_NO_OPEN_BROWSER=true` | Disable automatic browser opening on startup. Truthy values: `1`, `true`, `yes`. |
167168
| `CODEXSESS_CODEX_SANDBOX` | `workspace-write` | `CODEXSESS_CODEX_SANDBOX=read-only` | Sandbox mode passed to `codex exec`. |
168169
| `CODEXSESS_CLEAN_EXEC` | `true` | `CODEXSESS_CLEAN_EXEC=false` | Run Codex execution in isolated mode (`true`) or normal environment (`false`). |
@@ -195,6 +196,15 @@ curl -fsSL https://raw.githubusercontent.com/rickicode/CodexSess/main/scripts/in
195196
curl -fsSL https://raw.githubusercontent.com/rickicode/CodexSess/main/scripts/install.sh | bash -s -- --mode update
196197
```
197198

199+
GUI mode bind override (via `~/.bashrc`):
200+
201+
```bash
202+
echo 'export CODEXSESS_BIND_ADDR=0.0.0.0:3061' >> ~/.bashrc
203+
source ~/.bashrc
204+
```
205+
206+
Then restart CodexSess GUI session.
207+
198208
Windows installation:
199209
- Download `.exe` directly from:
200210
- https://github.com/rickicode/CodexSess/releases/latest

internal/config/config.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"encoding/hex"
77
"errors"
88
"fmt"
9+
"net"
910
"os"
1011
"path/filepath"
1112
"runtime"
@@ -142,7 +143,18 @@ func resolveBindAddr() string {
142143
port = parsed
143144
}
144145
}
145-
return fmt.Sprintf("127.0.0.1:%d", port)
146+
if raw := strings.TrimSpace(os.Getenv("CODEXSESS_BIND_ADDR")); raw != "" {
147+
if strings.HasPrefix(raw, ":") {
148+
return "0.0.0.0" + raw
149+
}
150+
if _, _, err := net.SplitHostPort(raw); err == nil {
151+
return raw
152+
}
153+
if !strings.Contains(raw, ":") {
154+
return fmt.Sprintf("%s:%d", raw, port)
155+
}
156+
}
157+
return fmt.Sprintf("0.0.0.0:%d", port)
146158
}
147159

148160
func defaultDataDir(home string) string {

internal/config/config_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,27 @@ func TestDefaultConfig(t *testing.T) {
1414
t.Fatal("MasterKeyPath empty")
1515
}
1616
}
17+
18+
func TestResolveBindAddr_DefaultIsAllInterfaces(t *testing.T) {
19+
t.Setenv("PORT", "")
20+
t.Setenv("CODEXSESS_BIND_ADDR", "")
21+
if got := resolveBindAddr(); got != "0.0.0.0:3061" {
22+
t.Fatalf("unexpected default bind addr: %q", got)
23+
}
24+
}
25+
26+
func TestResolveBindAddr_UsesPortEnv(t *testing.T) {
27+
t.Setenv("PORT", "4021")
28+
t.Setenv("CODEXSESS_BIND_ADDR", "")
29+
if got := resolveBindAddr(); got != "0.0.0.0:4021" {
30+
t.Fatalf("unexpected bind addr with PORT: %q", got)
31+
}
32+
}
33+
34+
func TestResolveBindAddr_UsesExplicitBindAddr(t *testing.T) {
35+
t.Setenv("PORT", "3061")
36+
t.Setenv("CODEXSESS_BIND_ADDR", "127.0.0.1:9090")
37+
if got := resolveBindAddr(); got != "127.0.0.1:9090" {
38+
t.Fatalf("unexpected explicit bind addr: %q", got)
39+
}
40+
}

0 commit comments

Comments
 (0)