Skip to content

Commit ebc56ab

Browse files
authored
Merge branch 'master' into docs/docker-disk-maintenance
2 parents 072889d + 3efc9c7 commit ebc56ab

7 files changed

Lines changed: 101 additions & 29 deletions

File tree

‎.devcontainer/init-plugins.sh‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,11 @@ done
4646

4747
# Initialize rtk global hook for Claude Code (auto-rewrite mode).
4848
# --hook-only: installs only the PreToolUse rewrite hook, no workspace artifacts.
49-
# WORKAROUND: RTK ≥0.36.0 added a GDPR telemetry consent prompt that hangs in
50-
# non-interactive environments. timeout + RTK_TELEMETRY_DISABLED work around it.
51-
# Remove when upstream fixes it: https://github.com/rtk-ai/rtk/issues/1307
49+
# RTK_TELEMETRY_DISABLED=1 is the supported opt-out, not a workaround: since
50+
# rtk-ai/rtk#2477 (v0.44.0+) it short-circuits the telemetry consent prompt that
51+
# would otherwise block on stdin here. rtk's own TTY check is not enough — a
52+
# devcontainer postCreateCommand gets a pseudo-TTY, so the prompt believes it is
53+
# interactive. timeout stays as a backstop against a future init-time hang.
5254
echo "Initializing rtk (token optimizer)..."
5355
RTK_TELEMETRY_DISABLED=1 timeout 10 rtk init -g --hook-only --auto-patch || {
5456
echo "Note: rtk init may have already been configured or rtk not available"

‎.github/renovate.json5‎

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,17 @@
2929
},
3030
{
3131
// Group the four tools into one PR and auto-merge once CI passes.
32-
// platformAutomerge:false => Renovate performs the merge itself only
33-
// after it observes the branch tests are green, so CI gating needs no
34-
// branch-protection rule. (Optional hardening: enable branch protection
35-
// requiring the CI checks and set platformAutomerge:true for native
36-
// GitHub auto-merge.)
32+
//
33+
// Relies on Renovate's default platformAutomerge:true — GitHub's native
34+
// auto-merge merges on green with no second Renovate run. The previous
35+
// explicit platformAutomerge:false is what broke this: only a Renovate
36+
// run could merge, and every run found a newer claude-code, force-pushed
37+
// the branch and ended before CI finished (#121 sat green for 3.5 weeks).
38+
//
39+
// Requires: repo setting "Allow auto-merge", and a ruleset on master
40+
// requiring the "CI complete" check (.github/workflows/ci.yml). Without
41+
// that required check nothing blocks the PR, GitHub never offers native
42+
// auto-merge, and Renovate silently falls back to the broken path.
3743
matchPackageNames: [
3844
'rtk-ai/rtk',
3945
'umputun/ralphex',
@@ -42,7 +48,18 @@
4248
],
4349
groupName: 'devcontainer agent tools',
4450
automerge: true,
45-
platformAutomerge: false,
51+
52+
// These bumps merge unreviewed and publish straight to ghcr.io, so let a
53+
// release soak before adopting it. internalChecksFilter defaults to
54+
// 'strict', so a too-young version is simply not offered yet — the group
55+
// PR carries whichever tools are currently eligible.
56+
minimumReleaseAge: '3 days',
57+
},
58+
{
59+
// ...except claude-code, which is tracked at latest deliberately.
60+
// Later packageRules win, so this clears the soak period above.
61+
matchPackageNames: ['@anthropic-ai/claude-code'],
62+
minimumReleaseAge: null,
4663
},
4764
],
4865
}

‎.github/workflows/ci.yml‎

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@ name: CI
33
on:
44
pull_request:
55
branches: [master]
6-
paths:
7-
- '**/Dockerfile'
8-
- '**/*.sh'
9-
- '.github/workflows/**'
10-
- '.hadolint.yaml'
6+
# Deliberately unfiltered: "CI complete" below is the required status check
7+
# for master, and a required check that never runs blocks a PR forever -- a
8+
# docs-only PR would deadlock. Image builds are still skipped per-image via
9+
# detect-changes; the always-on jobs are lint-only and take seconds.
1110

1211
concurrency:
1312
group: ci-${{ github.event.pull_request.number || github.ref }}
@@ -194,3 +193,52 @@ jobs:
194193
IMAGE_TAG: ${{ matrix.image }}:test
195194
VERIFY_CMD: ${{ matrix.verify }}
196195
run: docker run --rm --entrypoint sh "$IMAGE_TAG" -c "$VERIFY_CMD"
196+
197+
# -- Single required status check for branch protection ------------------
198+
# Aggregates every job above so master needs exactly one required check.
199+
# Passes when each job succeeded or was legitimately skipped (path-filtered
200+
# builds), and fails if any job failed or was cancelled.
201+
#
202+
# Any job added to this workflow must also be added to `needs` below: this is
203+
# the only required check on master and Renovate auto-merges on it, so an
204+
# unwatched job would go red while the gate stayed green. The first step
205+
# enforces that rather than trusting anyone to remember.
206+
ci-complete:
207+
name: CI complete
208+
# always(), not !cancelled(): GitHub counts a *skipped* required check as
209+
# passing, so !cancelled() would let a cancelled run report a green gate.
210+
if: always()
211+
needs: [lint-dockerfiles, lint-workflows, detect-changes, build-and-verify]
212+
runs-on: ubuntu-latest
213+
steps:
214+
- name: Checkout repository
215+
uses: actions/checkout@v6
216+
217+
- name: Verify every job is watched
218+
env:
219+
WATCHED: ${{ toJSON(needs) }}
220+
run: |
221+
missing=""
222+
for job in $(yq '.jobs | keys | .[]' .github/workflows/ci.yml); do
223+
[ "$job" = "ci-complete" ] && continue
224+
jq -e --arg j "$job" 'has($j)' <<< "$WATCHED" > /dev/null || missing="$missing $job"
225+
done
226+
if [ -n "$missing" ]; then
227+
echo "::error::Jobs missing from ci-complete.needs:$missing"
228+
exit 1
229+
fi
230+
231+
- name: Check results of all CI jobs
232+
env:
233+
WATCHED: ${{ toJSON(needs) }}
234+
run: |
235+
jq -r 'to_entries[] | "\(.key): \(.value.result)"' <<< "$WATCHED"
236+
bad=$(jq -r '
237+
to_entries[]
238+
| select(.value.result != "success" and .value.result != "skipped")
239+
| "\(.key) (\(.value.result))"' <<< "$WATCHED")
240+
if [ -n "$bad" ]; then
241+
echo "::error::CI jobs did not pass: $(echo "$bad" | tr '\n' ' ')"
242+
exit 1
243+
fi
244+
echo "All CI jobs passed or were skipped."

‎claude-code/.devcontainer/Dockerfile‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
FROM alpine:3.21 AS rtk-download
2121
RUN apk add --no-cache curl
2222
# renovate: datasource=github-releases depName=rtk-ai/rtk
23-
ARG RTK_VERSION=0.43.0
23+
ARG RTK_VERSION=0.48.0
2424
RUN set -eux; \
2525
ARCH="$(uname -m)"; \
2626
case "$ARCH" in \
@@ -36,7 +36,7 @@ RUN set -eux; \
3636
FROM alpine:3.21 AS ralphex-download
3737
RUN apk add --no-cache curl
3838
# renovate: datasource=github-releases depName=umputun/ralphex
39-
ARG RALPHEX_VERSION=1.6.0
39+
ARG RALPHEX_VERSION=1.7.0
4040
RUN set -eux; \
4141
ARCH="$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')"; \
4242
curl -fsSL -o /tmp/ralphex.tar.gz \
@@ -184,7 +184,7 @@ USER node
184184
# A later `chown -R` in another layer would duplicate every file (overlayfs
185185
# treats an ownership change as a rewrite), adding hundreds of MB.
186186
# renovate: datasource=npm depName=@anthropic-ai/claude-code
187-
ARG CLAUDE_CODE_VERSION=2.1.216
187+
ARG CLAUDE_CODE_VERSION=2.1.266
188188
RUN npm install -g @anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}
189189

190190
# ─── DEFAULT — full dev environment ───────────────────────────────────────────
@@ -229,7 +229,7 @@ ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 \
229229
# Installed as the node user (see claude-code install above for rationale).
230230
# Version pinned and kept up to date by Renovate (see .github/renovate.json5).
231231
# renovate: datasource=npm depName=agent-browser
232-
ARG AGENT_BROWSER_VERSION=0.32.3
232+
ARG AGENT_BROWSER_VERSION=0.37.1
233233
RUN npm install -g agent-browser@${AGENT_BROWSER_VERSION}
234234

235235
LABEL org.opencontainers.image.source="https://github.com/gatezh/devcontainers" \

‎claude-code/.devcontainer/init-plugins.sh‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,11 @@ done
7070
# ── rtk init (token-optimized CLI proxy) ────────────────────────────────────
7171
# Global hook-first mode: installs only the PreToolUse rewrite hook to ~/.claude/,
7272
# no workspace artifacts (CLAUDE.md, .rtk/). Safe to run multiple times.
73-
# WORKAROUND: RTK ≥0.36.0 added a GDPR telemetry consent prompt that hangs in
74-
# non-interactive environments. timeout + RTK_TELEMETRY_DISABLED work around it.
75-
# Remove when upstream fixes it: https://github.com/rtk-ai/rtk/issues/1307
73+
# RTK_TELEMETRY_DISABLED=1 is the supported opt-out, not a workaround: since
74+
# rtk-ai/rtk#2477 (v0.44.0+) it short-circuits the telemetry consent prompt that
75+
# would otherwise block on stdin here. rtk's own TTY check is not enough — a
76+
# devcontainer postCreateCommand gets a pseudo-TTY, so the prompt believes it is
77+
# interactive. timeout stays as a backstop against a future init-time hang.
7678
if command -v rtk &>/dev/null; then
7779
RTK_TELEMETRY_DISABLED=1 timeout 10 rtk init -g --hook-only --auto-patch 2>/dev/null || true
7880
fi

‎ralphex-fe/Dockerfile‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ RUN set -eux; \
4848
FROM alpine:3.21 AS rtk-download
4949
RUN apk add --no-cache curl
5050
# renovate: datasource=github-releases depName=rtk-ai/rtk
51-
ARG RTK_VERSION=0.43.0
51+
ARG RTK_VERSION=0.48.0
5252
RUN set -eux; \
5353
ARCH="$(uname -m)"; \
5454
case "$ARCH" in \
@@ -65,7 +65,7 @@ RUN set -eux; \
6565
FROM alpine:3.21 AS ralphex-download
6666
RUN apk add --no-cache curl
6767
# renovate: datasource=github-releases depName=umputun/ralphex
68-
ARG RALPHEX_VERSION=1.6.0
68+
ARG RALPHEX_VERSION=1.7.0
6969
RUN set -eux; \
7070
ARCH="$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')"; \
7171
curl -fsSL -o /tmp/ralphex.tar.gz \
@@ -160,7 +160,7 @@ WORKDIR /workspace
160160
# See: claude-code/.devcontainer/Dockerfile for rationale.
161161
# Version pinned and kept up to date by Renovate (see .github/renovate.json5).
162162
# renovate: datasource=npm depName=@anthropic-ai/claude-code
163-
ARG CLAUDE_CODE_VERSION=2.1.216
163+
ARG CLAUDE_CODE_VERSION=2.1.266
164164
RUN --mount=type=cache,target=/root/.npm \
165165
npm install -g @anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}
166166

‎ralphex-fe/init-docker.sh‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,14 @@ if [ -d /mnt/claude ]; then
2929
chown -R app:app /home/app/.claude
3030

3131
# ── RTK: ensure rewrite hook is configured ─────────────────────────────
32-
# Host mount usually brings the hook, but init idempotently to cover
33-
# standalone usage (no host mount). --hook-only avoids workspace artifacts.
34-
# WORKAROUND: RTK ≥0.36.0 added a GDPR telemetry consent prompt that hangs
35-
# in non-interactive environments. Remove when upstream fixes it:
36-
# https://github.com/rtk-ai/rtk/issues/1307
32+
# The host mount usually brings the hook; re-init idempotently in case the
33+
# mounted ~/.claude carries none. --hook-only avoids workspace artifacts.
34+
# Scope: this sits inside the /mnt/claude guard, so a container started
35+
# without the host mount gets no rtk hook and rtk stays inert.
36+
# RTK_TELEMETRY_DISABLED=1 is the supported opt-out, not a workaround:
37+
# since rtk-ai/rtk#2477 (v0.44.0+) it short-circuits the telemetry consent
38+
# prompt that would otherwise block on stdin here. timeout stays as a
39+
# backstop against a future init-time hang.
3740
if command -v rtk >/dev/null 2>&1; then
3841
RTK_TELEMETRY_DISABLED=1 gosu app timeout 10 rtk init -g --hook-only --auto-patch 2>/dev/null || true
3942
fi

0 commit comments

Comments
 (0)