From 439ee45f7873d3d62903e85de6f882674a146b73 Mon Sep 17 00:00:00 2001 From: Dmytro Smirnov Date: Wed, 8 Jul 2026 20:05:22 +0300 Subject: [PATCH 1/8] chore: update worker nodejs dependency automation --- .github/workflows/codeql.yml | 6 +- .../workflows/docker-dependency-updater.yml | 609 ++++++++++++++++++ .github/workflows/tests.yml | 2 +- .rabbit/README.md | 7 + .rabbit/context.yaml | 102 +++ Dockerfile | 4 +- README.md | 2 + ci/prompts/docker-dependency-apt.md | 6 + ci/prompts/docker-dependency-guardrails.md | 17 + ci/prompts/docker-dependency-nonapt.md | 7 + ci/prompts/docker-dependency-output.md | 21 + docs/README.md | 7 + 12 files changed, 784 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/docker-dependency-updater.yml create mode 100644 .rabbit/README.md create mode 100644 .rabbit/context.yaml create mode 100644 ci/prompts/docker-dependency-apt.md create mode 100644 ci/prompts/docker-dependency-guardrails.md create mode 100644 ci/prompts/docker-dependency-nonapt.md create mode 100644 ci/prompts/docker-dependency-output.md create mode 100644 docs/README.md diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 4ad43e9..815e4c1 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Install ShellCheck run: sudo apt-get install -y shellcheck @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Install hadolint run: | @@ -48,7 +48,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Install yamllint run: | diff --git a/.github/workflows/docker-dependency-updater.yml b/.github/workflows/docker-dependency-updater.yml new file mode 100644 index 0000000..06581d1 --- /dev/null +++ b/.github/workflows/docker-dependency-updater.yml @@ -0,0 +1,609 @@ +--- +name: udx-automation / worker-nodejs dependency upgrade + +"on": + schedule: + - cron: "0 5 * * 1" + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +env: + DOCKERFILE: Dockerfile + PROBE_DOCKERFILE: .tmp/dependency-probe/Dockerfile + REPORT_PATH: docker-dependency-report.json + UPDATE_BRANCH: udx-docker-dependency-updates + PR_TITLE: "chore(deps): docker dependency upgrade" + PR_TEAM_REVIEWER: worker + PR_LABELS: |- + docker + dependencies + PR_AUTO_MERGE: "false" + PR_MERGE_METHOD: squash + COMMIT_MESSAGE: "chore(deps): update Docker dependency pins" + COPILOT_CLI_VERSION: "1.0.68" + UPLOAD_COPILOT_SESSION: "true" + COPILOT_PROMPT_PARTS: >- + ci/prompts/docker-dependency-guardrails.md + ci/prompts/docker-dependency-apt.md + ci/prompts/docker-dependency-nonapt.md + ci/prompts/docker-dependency-output.md + +jobs: + config: + runs-on: ubuntu-24.04 + timeout-minutes: 5 + + permissions: + contents: read + pull-requests: read + + outputs: + dockerfile: ${{ steps.config.outputs.dockerfile }} + existing_pr_found: ${{ steps.existing-pr.outputs.found }} + image: ${{ steps.config.outputs.image }} + prompt_parts: ${{ steps.config.outputs.prompt_parts }} + probe_dockerfile: ${{ steps.config.outputs.probe_dockerfile }} + report_path: ${{ steps.config.outputs.report_path }} + update_branch: ${{ steps.config.outputs.update_branch }} + pr_title: ${{ steps.config.outputs.pr_title }} + pr_auto_merge: ${{ steps.config.outputs.pr_auto_merge }} + pr_merge_method: ${{ steps.config.outputs.pr_merge_method }} + commit_message: ${{ steps.config.outputs.commit_message }} + copilot_cli_version: ${{ steps.config.outputs.copilot_cli_version }} + upload_copilot_session: ${{ steps.config.outputs.upload_copilot_session }} + should_run: ${{ steps.decision.outputs.should_run }} + skip_reason: ${{ steps.decision.outputs.skip_reason }} + + steps: + - name: Checkout repository + uses: actions/checkout@v7 + + - name: Load dependency updater defaults + id: config + run: | + set -euo pipefail + + { + echo "image=worker-nodejs-deps-probe:${GITHUB_RUN_ID}" + echo "dockerfile=${DOCKERFILE}" + echo "prompt_parts=${COPILOT_PROMPT_PARTS}" + echo "probe_dockerfile=${PROBE_DOCKERFILE}" + echo "report_path=${REPORT_PATH}" + echo "update_branch=${UPDATE_BRANCH}" + echo "pr_title=${PR_TITLE}" + echo "pr_auto_merge=${PR_AUTO_MERGE}" + echo "pr_merge_method=${PR_MERGE_METHOD}" + echo "commit_message=${COMMIT_MESSAGE}" + echo "copilot_cli_version=${COPILOT_CLI_VERSION}" + echo "upload_copilot_session=${UPLOAD_COPILOT_SESSION}" + } >> "${GITHUB_OUTPUT}" + + test -n "${DOCKERFILE}" + test -n "${COPILOT_PROMPT_PARTS}" + test -n "${COPILOT_CLI_VERSION}" + test -n "${PROBE_DOCKERFILE}" + test -n "${UPLOAD_COPILOT_SESSION}" + test -f "${DOCKERFILE}" + for prompt_part in ${COPILOT_PROMPT_PARTS}; do + test -s "${prompt_part}" + done + echo "Dependency updater defaults loaded for ${DOCKERFILE}" + + - name: Stop if an update PR is already open + id: existing-pr + uses: actions/github-script@v9 + env: + UPDATE_BRANCH: ${{ steps.config.outputs.update_branch }} + with: + script: | + const owner = context.repo.owner; + const repo = context.repo.repo; + const head = `${owner}:${process.env.UPDATE_BRANCH}`; + + const prs = await github.rest.pulls.list({ + owner, + repo, + state: "open", + head, + per_page: 100 + }); + + core.setOutput("found", prs.data.length > 0 ? "true" : "false"); + if (prs.data.length > 0) { + console.log(`Update PR already open: ${prs.data[0].html_url}`); + } else { + console.log(`No open update PR found for ${head}`); + } + + - name: Decide updater execution + id: decision + run: | + set -euo pipefail + + if [ "${EXISTING_PR_FOUND}" = "true" ]; then + echo "should_run=false" >> "${GITHUB_OUTPUT}" + echo "skip_reason=Update PR already open for ${UPDATE_BRANCH}" \ + >> "${GITHUB_OUTPUT}" + echo "Config decision: skip; update PR already open." + exit 0 + fi + + echo "should_run=true" >> "${GITHUB_OUTPUT}" + echo "skip_reason=" >> "${GITHUB_OUTPUT}" + echo "Config decision: run upgrade; no open updater PR found." + env: + EXISTING_PR_FOUND: ${{ steps.existing-pr.outputs.found }} + UPDATE_BRANCH: ${{ steps.config.outputs.update_branch }} + + upgrade: + needs: config + if: needs.config.outputs.should_run == 'true' + runs-on: ubuntu-24.04 + timeout-minutes: 20 + + outputs: + apt_count: ${{ steps.probe.outputs.apt_count }} + base_image: ${{ steps.probe.outputs.base_image }} + changed: ${{ steps.changes.outputs.changed }} + node_version: ${{ steps.probe.outputs.node_version }} + pr_url: ${{ steps.create-pr.outputs.pull-request-url }} + + permissions: + contents: write + pull-requests: write + + steps: + - name: Checkout repository + uses: actions/checkout@v7 + with: + ref: ${{ github.ref }} + + - name: Generate dependency probe report + id: probe + timeout-minutes: 8 + run: | + set -euo pipefail + + probe_dir="$(dirname "${PROBE_DOCKERFILE}")" + apt_versions_path="${probe_dir}/apt.tsv" + + mkdir -p "${probe_dir}" + + awk ' + /apt-get install -y --no-install-recommends/ { in_apt = 1 } + { + line = $0 + if (in_apt) { + gsub(/=("[^"]*"|[^[:space:]\\]+)/, "", line) + } + print line + if (in_apt && line ~ /&&[[:space:]]*\\?$/) { + in_apt = 0 + } + } + ' "${DOCKERFILE}" > "${PROBE_DOCKERFILE}" + + node_version="$(curl -fsSL https://nodejs.org/dist/index.json \ + | jq -r '[.[] | select(.lts != false)][0].version | ltrimstr("v")')" + test -n "${node_version}" + + base_image="$(curl -fsSL \ + "https://api.github.com/repos/udx/worker/releases/latest" \ + | jq -r '.tag_name')" + test -n "${base_image}" + base_image_ref="usabilitydynamics/udx-worker:${base_image}" + + perl -0pi -e \ + "s#^FROM usabilitydynamics/udx-worker:.*#FROM ${base_image_ref}#m" \ + "${PROBE_DOCKERFILE}" + perl -0pi -e \ + "s/^ARG NODE_VERSION=.*/ARG NODE_VERSION=${node_version}/m" \ + "${PROBE_DOCKERFILE}" + + apt_packages=(xz-utils) + + docker build --pull --no-cache -f "${PROBE_DOCKERFILE}" \ + -t "${PROBE_IMAGE}" . + docker run -i --rm --entrypoint bash "${PROBE_IMAGE}" \ + -s -- "${apt_packages[@]}" > "${apt_versions_path}" <<'EOF' + set -euo pipefail + + dpkg-query -W -f='${binary:Package}\t${Version}\n' "$@" + EOF + strategy_summary="Use the latest udx-worker release, latest Node.js " + strategy_summary="${strategy_summary}LTS release, and a no-pin apt " + strategy_summary="${strategy_summary}probe for xz-utils." + + non_apt_path="${probe_dir}/non-apt.json" + node <<'NODE' > "${non_apt_path}" + const fs = require("node:fs"); + + const dockerfile = fs.readFileSync(process.env.DOCKERFILE, "utf8"); + const pins = []; + const urls = []; + + for (const line of dockerfile.split(/\r?\n/)) { + const argMatch = line.match(/^ARG\s+([A-Za-z_][A-Za-z0-9_]*)=(.+)$/); + if (argMatch) { + pins.push({ + kind: "ARG", + name: argMatch[1], + value: argMatch[2].replace(/^["']|["']$/g, "") + }); + } + + for (const urlMatch of line.matchAll(/https?:\/\/[^"'\s]+/g)) { + urls.push(urlMatch[0]); + } + } + + fs.writeFileSync( + process.stdout.fd, + JSON.stringify({method: "Dockerfile ARG and URL inventory", pins, urls}, null, 2) + ); + NODE + + jq -n \ + --arg generated_at "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ + --arg base_image "${base_image}" \ + --arg dockerfile "${DOCKERFILE}" \ + --arg node_version "${node_version}" \ + --arg probe_dockerfile "${PROBE_DOCKERFILE}" \ + --arg strategy_summary "${strategy_summary}" \ + --slurpfile non_apt "${non_apt_path}" \ + --rawfile apt_versions "${apt_versions_path}" \ + '{ + generated_at: $generated_at, + method: "worker-nodejs dependency probe", + base_image: "usabilitydynamics/udx-worker:" + $base_image, + node_version: $node_version, + strategy: { + summary: $strategy_summary, + dockerfile: $dockerfile, + probe_dockerfile: $probe_dockerfile + }, + dependencies: { + apt: ( + $apt_versions + | split("\n") + | map(select(length > 0)) + | map(split("\t") | {name: .[0], installed: .[1]}) + ) + , + non_apt: $non_apt[0] + } + }' > "${PROBE_REPORT}" + + apt_count="$(jq '.dependencies.apt | length' "${PROBE_REPORT}")" + echo "apt_count=${apt_count}" >> "${GITHUB_OUTPUT}" + echo "base_image=${base_image}" >> "${GITHUB_OUTPUT}" + echo "node_version=${node_version}" >> "${GITHUB_OUTPUT}" + echo "Upgrade probe: wrote ${PROBE_REPORT}." + env: + DOCKERFILE: ${{ needs.config.outputs.dockerfile }} + PROBE_DOCKERFILE: ${{ needs.config.outputs.probe_dockerfile }} + PROBE_IMAGE: ${{ needs.config.outputs.image }} + PROBE_REPORT: ${{ needs.config.outputs.report_path }} + + - name: Upload dependency report + uses: actions/upload-artifact@v6 + timeout-minutes: 3 + with: + name: docker-dependency-report + path: | + ${{ needs.config.outputs.report_path }} + ${{ needs.config.outputs.probe_dockerfile }} + + - name: Check Copilot availability + id: copilot-availability + timeout-minutes: 1 + run: | + set -euo pipefail + + if [ -n "${COPILOT_GITHUB_TOKEN:-}" ]; then + echo "available=true" >> "${GITHUB_OUTPUT}" + echo "Copilot CLI review is available." + else + echo "available=false" >> "${GITHUB_OUTPUT}" + echo "Copilot CLI review skipped; COPILOT_GITHUB_TOKEN is not set." + fi + env: + COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} + + - name: Update Dockerfile pins + timeout-minutes: 3 + run: | + set -euo pipefail + + base_image="$(jq -r '.base_image' "${REPORT_PATH}")" + node_version="$(jq -r '.node_version' "${REPORT_PATH}")" + xz_version="$(jq -r \ + '.dependencies.apt[] | select(.name == "xz-utils") | .installed' \ + "${REPORT_PATH}")" + + test -n "${base_image}" + test -n "${node_version}" + test -n "${xz_version}" + + perl -0pi -e \ + "s#^FROM usabilitydynamics/udx-worker:.*#FROM ${base_image}#m" \ + "${DOCKERFILE}" + perl -0pi -e \ + "s/^ARG NODE_VERSION=.*/ARG NODE_VERSION=${node_version}/m" \ + "${DOCKERFILE}" + perl -0pi -e \ + "s/xz-utils=[^[:space:]\\]+/xz-utils=${xz_version}/" \ + "${DOCKERFILE}" + + echo "Upgrade pins:" + echo "- Base image: ${base_image}" + echo "- Node.js: ${node_version}" + echo "- xz-utils: ${xz_version}" + env: + DOCKERFILE: ${{ needs.config.outputs.dockerfile }} + REPORT_PATH: ${{ needs.config.outputs.report_path }} + + - name: Set up Node.js for Copilot CLI + if: steps.copilot-availability.outputs.available == 'true' + uses: actions/setup-node@v7 + timeout-minutes: 3 + with: + node-version: "22" + + - name: Install Copilot CLI + if: steps.copilot-availability.outputs.available == 'true' + timeout-minutes: 3 + run: | + npm install -g "@github/copilot@${COPILOT_CLI_VERSION}" + echo "Upgrade setup: installed Copilot CLI ${COPILOT_CLI_VERSION}" + env: + COPILOT_CLI_VERSION: ${{ needs.config.outputs.copilot_cli_version }} + + - name: Review Dockerfile with Copilot CLI + if: steps.copilot-availability.outputs.available == 'true' + timeout-minutes: 8 + run: | + set -euo pipefail + + test -n "${DOCKERFILE}" + test -n "${REPORT_PATH}" + test -n "${PROMPT_PARTS}" + test -f "${DOCKERFILE}" + test -s "${REPORT_PATH}" + jq -e '.dependencies.apt and .dependencies.non_apt' \ + "${REPORT_PATH}" >/dev/null + + prompt_path=".tmp/dependency-upgrade/copilot-prompt.md" + mkdir -p "$(dirname "${prompt_path}")" + : > "${prompt_path}" + for prompt_part in ${PROMPT_PARTS}; do + test -s "${prompt_part}" + { + cat "${prompt_part}" + echo + } >> "${prompt_path}" + done + test -s "${prompt_path}" + + copilot_args=( + --prompt "$(cat "${prompt_path}")" + --allow-tool=write + --deny-tool=shell + --allow-all-urls + --no-ask-user + --no-auto-update + --silent + ) + + if [ "${UPLOAD_COPILOT_SESSION}" = "true" ]; then + copilot_args+=(--share copilot-docker-dependency-session.md) + fi + + copilot "${copilot_args[@]}" + echo "Upgrade Copilot: completed" + env: + COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} + COPILOT_AUTO_UPDATE: "false" + DOCKERFILE: ${{ needs.config.outputs.dockerfile }} + PROMPT_PARTS: ${{ needs.config.outputs.prompt_parts }} + REPORT_PATH: ${{ needs.config.outputs.report_path }} + UPLOAD_COPILOT_SESSION: ${{ needs.config.outputs.upload_copilot_session }} + + - name: Guard Dockerfile-only changes + timeout-minutes: 1 + run: | + set -euo pipefail + + unexpected_changes="$(git diff --name-only \ + | awk -v dockerfile="${DOCKERFILE}" '$0 != dockerfile')" + if [ -n "${unexpected_changes}" ]; then + echo "Upgrade guard: modified files outside ${DOCKERFILE}:" >&2 + printf '%s\n' "${unexpected_changes}" >&2 + exit 1 + fi + + echo "Upgrade guard: tracked changes are limited to ${DOCKERFILE}" + env: + DOCKERFILE: ${{ needs.config.outputs.dockerfile }} + + - name: Detect changes + id: changes + run: | + set -euo pipefail + if git diff --quiet -- "${DOCKERFILE}"; then + echo "changed=false" >> "${GITHUB_OUTPUT}" + echo "Upgrade changes: no ${DOCKERFILE} changes" + else + echo "changed=true" >> "${GITHUB_OUTPUT}" + git diff -- "${DOCKERFILE}" > docker-dependency-update.diff + changed_lines="$(wc -l < docker-dependency-update.diff | tr -d ' ')" + echo "Upgrade changes: ${DOCKERFILE} changed; ${changed_lines} lines" + fi + env: + DOCKERFILE: ${{ needs.config.outputs.dockerfile }} + + - name: Prepare pull request body + if: steps.changes.outputs.changed == 'true' + run: | + { + echo "## Summary" + echo + echo "Updates worker-nodejs Dockerfile dependency pins." + echo + echo "## Evidence" + echo + echo "- Probe report artifact: \`${REPORT_PATH}\`" + if [ "${COPILOT_AVAILABLE}" = "true" ]; then + echo "- Copilot CLI review: enabled" + else + echo "- Copilot CLI review: skipped; token not configured" + fi + if [ "${COPILOT_AVAILABLE}" = "true" ] && + [ "${UPLOAD_COPILOT_SESSION}" = "true" ]; then + echo "- Copilot session artifact: \`copilot-docker-dependency-session.md\`" + fi + echo "- Build validation: repository Docker/CI workflows" + echo + echo "## Diff" + echo + echo '```diff' + sed -n '1,220p' docker-dependency-update.diff + echo '```' + } > docker-dependency-pr-body.md + echo "Upgrade PR body: prepared docker-dependency-pr-body.md" + env: + COPILOT_AVAILABLE: ${{ steps.copilot-availability.outputs.available }} + REPORT_PATH: ${{ needs.config.outputs.report_path }} + UPLOAD_COPILOT_SESSION: ${{ needs.config.outputs.upload_copilot_session }} + + - name: Upload update diff + uses: actions/upload-artifact@v6 + timeout-minutes: 3 + with: + name: docker-dependency-update-diff + path: | + docker-dependency-update.diff + if-no-files-found: ignore + + - name: Upload Copilot session + if: >- + always() && + steps.copilot-availability.outputs.available == 'true' && + needs.config.outputs.upload_copilot_session == 'true' + uses: actions/upload-artifact@v6 + timeout-minutes: 3 + with: + name: docker-dependency-copilot-session + path: | + copilot-docker-dependency-session.md + docker-dependency-update.diff + if-no-files-found: ignore + + - name: Create pull request + id: create-pr + if: steps.changes.outputs.changed == 'true' + uses: peter-evans/create-pull-request@v8 + timeout-minutes: 5 + with: + token: ${{ secrets.DEPENDABOT_REVIEWER_TOKEN || secrets.GH_TOKEN || github.token }} + author: udx-github <73100442+udx-github@users.noreply.github.com> + committer: udx-github <73100442+udx-github@users.noreply.github.com> + commit-message: ${{ needs.config.outputs.commit_message }} + title: ${{ needs.config.outputs.pr_title }} + body-path: docker-dependency-pr-body.md + branch: ${{ needs.config.outputs.update_branch }} + add-paths: ${{ needs.config.outputs.dockerfile }} + labels: ${{ env.PR_LABELS }} + team-reviewers: ${{ env.PR_TEAM_REVIEWER }} + draft: false + delete-branch: true + + - name: Enable pull request auto-merge + if: >- + steps.changes.outputs.changed == 'true' && + steps.create-pr.outputs.pull-request-url != '' && + needs.config.outputs.pr_auto_merge == 'true' + timeout-minutes: 3 + run: | + set -euo pipefail + + case "${MERGE_METHOD}" in + merge|rebase|squash) + if gh pr merge "${PR_URL}" --auto "--${MERGE_METHOD}"; then + echo "Enabled ${MERGE_METHOD} auto-merge for ${PR_URL}" + else + echo "Could not enable auto-merge for ${PR_URL}" >&2 + fi + ;; + *) + echo "Unsupported merge method: ${MERGE_METHOD}" >&2 + exit 1 + ;; + esac + env: + GH_TOKEN: ${{ secrets.DEPENDABOT_REVIEWER_TOKEN || secrets.GH_TOKEN || github.token }} + MERGE_METHOD: ${{ needs.config.outputs.pr_merge_method }} + PR_URL: ${{ steps.create-pr.outputs.pull-request-url }} + + report: + needs: + - config + - upgrade + if: always() + runs-on: ubuntu-24.04 + timeout-minutes: 5 + + steps: + - name: Write workflow summary + if: always() + run: | + pr_url="${PR_URL:-}" + if [ -z "${pr_url}" ]; then + pr_url="n/a" + fi + + skip_reason="${SKIP_REASON:-}" + if [ -z "${skip_reason}" ]; then + skip_reason="n/a" + fi + + apt_count="${APT_COUNT:-}" + if [ -z "${apt_count}" ]; then + apt_count="n/a" + fi + + changed="${CHANGED:-}" + if [ -z "${changed}" ]; then + changed="n/a" + fi + + { + echo "## udx-automation / worker-nodejs dependency upgrade" + echo + echo "- config: ${{ needs.config.result }}" + echo "- upgrade: ${{ needs.upgrade.result }}" + echo "- report: ${{ job.status }}" + echo "- Dockerfile: \`${DOCKERFILE}\`" + echo "- branch: \`${UPDATE_BRANCH}\`" + echo "- should run: \`${SHOULD_RUN}\`" + echo "- report artifact: \`${REPORT_PATH}\`" + echo "- apt packages: \`${apt_count}\`" + echo "- Dockerfile changed: \`${changed}\`" + echo "- PR: ${pr_url}" + echo "- skip: \`${skip_reason}\`" + } >> "${GITHUB_STEP_SUMMARY}" + env: + APT_COUNT: ${{ needs.upgrade.outputs.apt_count }} + CHANGED: ${{ needs.upgrade.outputs.changed }} + DOCKERFILE: ${{ needs.config.outputs.dockerfile }} + PR_URL: ${{ needs.upgrade.outputs.pr_url }} + REPORT_PATH: ${{ needs.config.outputs.report_path }} + SKIP_REASON: ${{ needs.config.outputs.skip_reason }} + SHOULD_RUN: ${{ needs.config.outputs.should_run }} + UPDATE_BRANCH: ${{ needs.config.outputs.update_branch }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index afd7235..87f8280 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Build image and run tests run: make test diff --git a/.rabbit/README.md b/.rabbit/README.md new file mode 100644 index 0000000..34aa0ed --- /dev/null +++ b/.rabbit/README.md @@ -0,0 +1,7 @@ +# Rabbit Context + +This directory keeps Rabbit-facing repo context and generated `dev.kit` evidence. + +- `context.yaml` is generated by `dev.kit repo`; do not edit it manually. +- Keep human-authored Rabbit CI notes, delivery entry points, and repo-specific workflow guidance in this README. +- After changing repo docs, manifests, scripts, or workflows, run `dev.kit repo` to refresh generated context. diff --git a/.rabbit/context.yaml b/.rabbit/context.yaml new file mode 100644 index 0000000..54ff3d9 --- /dev/null +++ b/.rabbit/context.yaml @@ -0,0 +1,102 @@ +# Generated by dev.kit repo — do not edit manually. +# Run `dev.kit repo` to refresh. +kind: repoContext +version: udx.dev/dev.kit/v1 +generator: + tool: dev.kit + repo: https://github.com/udx/dev.kit + version: 0.20.1 + generated_at: 2026-07-08T17:00:26Z + sources: + homepage: https://udx.dev/kit + repository: https://github.com/udx/dev.kit + package: https://www.npmjs.com/package/@udx/dev-kit + installation: https://github.com/udx/dev.kit/blob/latest/docs/installation.md + +repo: + name: worker-nodejs + archetype: manifest-repo + +# Refs — Direct-read files and paths that define the repo contract. +# Note: Include only files or directories a repo consumer should read before code exploration. +# Note: Prefer README, focused docs, workflows, manifests, and explicit operational files. +# Note: Exclude broad implementation directories unless they are the contract themselves. + +refs: + - ./README.md + - ./Makefile + - ./deploy.yml + - ./.github/workflows + - ./Dockerfile + - ./docs + +# Commands — Canonical repo entrypoints detected from strong repo signals. +# Note: Prefer declared make targets and package scripts before regex matches in docs. +# Note: Emit only commands that can be traced to a concrete source. +# Note: Record the source path so the command can be reviewed and corrected. + +commands: + verify: + run: make test + source: Makefile + build: + run: make build + source: Makefile + run: + run: make run + source: Makefile + +# Dependencies — Meaningful dependency-repo contracts such as reusable workflows, images, or versioned manifests this repo relies on. +# Note: Capture execution-shaping behavior defined outside the current checkout. +# Note: Avoid promoting standard package inventory or ordinary GitHub action refs into top-level context. +# Note: Normalize same-org versioned refs into repo slugs when possible. + +dependencies: + - repo: udx/reusable-workflows + kind: reusable workflow + resolved: true + archetype: manifest-repo + description: Reusable GitHub Actions workflow templates for CI/CD + used_by: + - .github/workflows/context7_sync.yml + - .github/workflows/docker-ops.yml + - repo: usabilitydynamics/udx-worker:0.46.0 + kind: base image + resolved: true + source_repo: udx/worker + archetype: manifest-repo + description: UDX Worker Docker image + used_by: + - Dockerfile + - repo: udx/worker + kind: manifest contract (deploy) + resolved: true + declared_as: udx.io/worker-v1/deploy + archetype: manifest-repo + description: UDX Worker Docker image + used_by: + - deploy.yml + +# Manifests — YAML files that define repo-specific workflow, deploy, or contract behavior. +# Note: Include custom config/manifests that materially shape repo behavior or contract understanding. +# Note: Do not include workflow YAML only because it lives under .github/workflows. +# Note: Promote workflow files only when they declare reusable workflow refs or other repo-specific execution contracts. +# Note: Prefer structured kind and description metadata from the manifest itself. +# Note: Include hidden or nested contract dirs when they contain repo-owned manifests with meaningful metadata. + +manifests: + - path: .github/workflows/context7_sync.yml + kind: githubWorkflow + - path: .github/workflows/docker-ops.yml + kind: githubWorkflow + - path: deploy.yml + kind: workerDeployConfig + declared_as: udx.io/worker-v1/deploy + source_repo: udx/worker + used_by: + - README.md + - src/examples/README.md + evidence: + - version: udx.io/worker-v1/deploy + - path reference: README.md + - path reference: src/examples/README.md diff --git a/Dockerfile b/Dockerfile index 680ce0e..ed31668 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,11 @@ # Use a pinned udx-worker release -FROM usabilitydynamics/udx-worker:0.41.0 +FROM usabilitydynamics/udx-worker:0.46.0 # Add metadata labels LABEL version="0.32.0" # Set build arguments for Node.js version and application port -ARG NODE_VERSION=24.13.1 +ARG NODE_VERSION=24.18.0 ARG APP_PORT=8080 # Add Node.js to PATH diff --git a/README.md b/README.md index 4bd91db..3708ef2 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,8 @@ make run-test TEST_SCRIPT=10_validate_environment.sh Build defaults for contributors live in `Makefile.variables` (Node.js version, ports, build args). +Repo context generated by `dev-kit repo` lives in `.rabbit/context.yaml`; Rabbit-facing workflow notes live in `.rabbit/README.md`. + ## Resources - Base image docs: https://github.com/udx/worker/tree/latest/docs diff --git a/ci/prompts/docker-dependency-apt.md b/ci/prompts/docker-dependency-apt.md new file mode 100644 index 0000000..93c3cff --- /dev/null +++ b/ci/prompts/docker-dependency-apt.md @@ -0,0 +1,6 @@ +Apt dependency rules: +- The dependency report resolves apt package versions for the configured Ubuntu base image using a no-pin apt probe. +- The no-pin apt probe is authoritative for apt package updates. +- For apt packages, update Dockerfile pins only from `dependencies.apt[].installed` in the dependency report. +- Do not use apt websites, package search pages, or guessed versions for apt pins. +- If an apt package from Dockerfile is missing from the report, leave that package unchanged and explain it in the changelog. diff --git a/ci/prompts/docker-dependency-guardrails.md b/ci/prompts/docker-dependency-guardrails.md new file mode 100644 index 0000000..2b2c64f --- /dev/null +++ b/ci/prompts/docker-dependency-guardrails.md @@ -0,0 +1,17 @@ +You are updating Dockerfile dependency pins for this repository. + +Inputs: +- Dockerfile: `Dockerfile` +- Dependency report: `docker-dependency-report.json` + +Hard boundaries: +- This is an edit-only dependency update task. +- Read both input files before editing. +- Edit only Dockerfile dependency pins and ARG/ENV values. +- Do not edit workflow files, docs, tests, or application code. +- Do not validate, build, test, run the container pipeline, inspect GitHub Actions runs, wait for workflows, create pull requests, commit, push, or request reviews. +- Do not run `docker`, `make`, test commands, CI commands, `gh run`, `gh workflow`, `gh pr`, `git commit`, `git push`, or any command that waits on external workflow state. +- Do not use vulnerability scanners or security reports to decide whether a dependency should be updated. +- Apt package updates must be backed by the dependency report. +- Non-apt package updates must be backed by the dependency report inventory plus clear upstream version evidence. +- If an update is not backed by the required evidence, leave it unchanged and mention why. diff --git a/ci/prompts/docker-dependency-nonapt.md b/ci/prompts/docker-dependency-nonapt.md new file mode 100644 index 0000000..f7c355c --- /dev/null +++ b/ci/prompts/docker-dependency-nonapt.md @@ -0,0 +1,7 @@ +Non-apt dependency rules: +- Use `dependencies.non_apt.pins` and `dependencies.non_apt.urls` from the dependency report as the starting inventory of Dockerfile-owned non-apt candidates. +- For `NODE_VERSION`, check the official Node.js release index and keep the latest stable LTS release from the same active LTS line unless the Dockerfile or repo docs explicitly require a different major version. +- Preserve the UDX Worker base image tag already selected by the deterministic updater unless clear upstream evidence shows a newer stable `udx/worker` release. +- Include the upstream source URL for every non-apt update in the changelog. +- Leave pins unchanged when the upstream source cannot be identified, cannot be checked, is ambiguous, or does not clearly show a newer stable release/version. +- Keep dynamically installed dependencies unpinned unless Dockerfile already pins them; mention them in the changelog only. diff --git a/ci/prompts/docker-dependency-output.md b/ci/prompts/docker-dependency-output.md new file mode 100644 index 0000000..e5a540c --- /dev/null +++ b/ci/prompts/docker-dependency-output.md @@ -0,0 +1,21 @@ +Output: +- Print a changelog using this template: + +```text +Docker dependency changelog + +Updated: +- : -> () + +Unchanged: +- : () + +Observed but not pinned: +- : () + +Notes: +- +``` + +- Omit empty sections except `Notes`. +- Do not claim build, test, scanner, or CI validation. diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..7625253 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,7 @@ +# Repository Docs + +Use this directory for durable, human-authored repo documentation. + +- Keep the root `README.md` as the entry point for what the repo is and how to work with it. +- Keep Rabbit-facing workflow notes in `.rabbit/README.md`. +- Treat `.rabbit/context.yaml` as generated evidence from `dev.kit repo`, not as hand-authored documentation. From 95feec707edf84ac7b2576a12ea22d4629d76273 Mon Sep 17 00:00:00 2001 From: Dmytro Smirnov Date: Wed, 8 Jul 2026 20:35:26 +0300 Subject: [PATCH 2/8] fix: address copilot dependency updater feedback --- .github/workflows/docker-dependency-updater.yml | 8 ++++++-- README.md | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-dependency-updater.yml b/.github/workflows/docker-dependency-updater.yml index 06581d1..233c92c 100644 --- a/.github/workflows/docker-dependency-updater.yml +++ b/.github/workflows/docker-dependency-updater.yml @@ -167,6 +167,8 @@ jobs: - name: Generate dependency probe report id: probe timeout-minutes: 8 + env: + GITHUB_TOKEN: ${{ github.token }} run: | set -euo pipefail @@ -189,11 +191,13 @@ jobs: } ' "${DOCKERFILE}" > "${PROBE_DOCKERFILE}" - node_version="$(curl -fsSL https://nodejs.org/dist/index.json \ + node_version="$(curl --retry 5 --retry-all-errors --retry-delay 2 -fsSL https://nodejs.org/dist/index.json \ | jq -r '[.[] | select(.lts != false)][0].version | ltrimstr("v")')" test -n "${node_version}" - base_image="$(curl -fsSL \ + base_image="$(curl --retry 5 --retry-all-errors --retry-delay 2 -fsSL \ + -H "Authorization: Bearer ${GITHUB_TOKEN}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ "https://api.github.com/repos/udx/worker/releases/latest" \ | jq -r '.tag_name')" test -n "${base_image}" diff --git a/README.md b/README.md index 3708ef2..ff8cfd0 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ make run-test TEST_SCRIPT=10_validate_environment.sh Build defaults for contributors live in `Makefile.variables` (Node.js version, ports, build args). -Repo context generated by `dev-kit repo` lives in `.rabbit/context.yaml`; Rabbit-facing workflow notes live in `.rabbit/README.md`. +Repo context generated by `dev.kit repo` lives in `.rabbit/context.yaml`; Rabbit-facing workflow notes live in `.rabbit/README.md`. ## Resources From 3c76fba4dd1a7c394d89420a6bca623fe30d219f Mon Sep 17 00:00:00 2001 From: Dmytro Smirnov Date: Wed, 8 Jul 2026 20:37:33 +0300 Subject: [PATCH 3/8] fix: repair dependency updater workflow yaml --- .github/workflows/docker-dependency-updater.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/docker-dependency-updater.yml b/.github/workflows/docker-dependency-updater.yml index 233c92c..08c3d9d 100644 --- a/.github/workflows/docker-dependency-updater.yml +++ b/.github/workflows/docker-dependency-updater.yml @@ -168,7 +168,11 @@ jobs: id: probe timeout-minutes: 8 env: + DOCKERFILE: ${{ needs.config.outputs.dockerfile }} GITHUB_TOKEN: ${{ github.token }} + PROBE_DOCKERFILE: ${{ needs.config.outputs.probe_dockerfile }} + PROBE_IMAGE: ${{ needs.config.outputs.image }} + PROBE_REPORT: ${{ needs.config.outputs.report_path }} run: | set -euo pipefail @@ -289,12 +293,6 @@ jobs: echo "base_image=${base_image}" >> "${GITHUB_OUTPUT}" echo "node_version=${node_version}" >> "${GITHUB_OUTPUT}" echo "Upgrade probe: wrote ${PROBE_REPORT}." - env: - DOCKERFILE: ${{ needs.config.outputs.dockerfile }} - PROBE_DOCKERFILE: ${{ needs.config.outputs.probe_dockerfile }} - PROBE_IMAGE: ${{ needs.config.outputs.image }} - PROBE_REPORT: ${{ needs.config.outputs.report_path }} - - name: Upload dependency report uses: actions/upload-artifact@v6 timeout-minutes: 3 From 57d49c86c4affc803d1de1cbc4e753ff7d2627ac Mon Sep 17 00:00:00 2001 From: Dmytro Smirnov Date: Wed, 8 Jul 2026 20:40:56 +0300 Subject: [PATCH 4/8] docs: remove deprecated worker deployment cli path --- .rabbit/context.yaml | 25 +++++++------ README.md | 31 +++++++--------- deploy.yml | 19 ---------- docs/worker-config.md | 51 +++++++++++++++++++++++++++ src/examples/README.md | 12 +++---- src/examples/simple-server/deploy.yml | 16 --------- worker.yaml | 11 ++++++ 7 files changed, 90 insertions(+), 75 deletions(-) delete mode 100644 deploy.yml create mode 100644 docs/worker-config.md delete mode 100644 src/examples/simple-server/deploy.yml create mode 100644 worker.yaml diff --git a/.rabbit/context.yaml b/.rabbit/context.yaml index 54ff3d9..6404772 100644 --- a/.rabbit/context.yaml +++ b/.rabbit/context.yaml @@ -6,7 +6,7 @@ generator: tool: dev.kit repo: https://github.com/udx/dev.kit version: 0.20.1 - generated_at: 2026-07-08T17:00:26Z + generated_at: 2026-07-08T17:39:47Z sources: homepage: https://udx.dev/kit repository: https://github.com/udx/dev.kit @@ -25,7 +25,7 @@ repo: refs: - ./README.md - ./Makefile - - ./deploy.yml + - ./worker.yaml - ./.github/workflows - ./Dockerfile - ./docs @@ -69,13 +69,13 @@ dependencies: used_by: - Dockerfile - repo: udx/worker - kind: manifest contract (deploy) + kind: manifest contract (config) resolved: true - declared_as: udx.io/worker-v1/deploy + declared_as: udx.io/worker-v1/config archetype: manifest-repo description: UDX Worker Docker image used_by: - - deploy.yml + - worker.yaml # Manifests — YAML files that define repo-specific workflow, deploy, or contract behavior. # Note: Include custom config/manifests that materially shape repo behavior or contract understanding. @@ -89,14 +89,13 @@ manifests: kind: githubWorkflow - path: .github/workflows/docker-ops.yml kind: githubWorkflow - - path: deploy.yml - kind: workerDeployConfig - declared_as: udx.io/worker-v1/deploy + - path: worker.yaml + kind: workerConfig + declared_as: udx.io/worker-v1/config source_repo: udx/worker used_by: - - README.md - - src/examples/README.md + - docs/worker-config.md evidence: - - version: udx.io/worker-v1/deploy - - path reference: README.md - - path reference: src/examples/README.md + - version: udx.io/worker-v1/config + - github reference: udx/worker + - path reference: docs/worker-config.md diff --git a/README.md b/README.md index ff8cfd0..3d65653 100644 --- a/README.md +++ b/README.md @@ -12,33 +12,27 @@ UDX Worker Node.js is a Docker image that provides a ready-to-use Node.js runtim ## Quick Start -Requirements: Docker and Node.js (for the CLI). +Requirements: Docker. -1. Install the deployment CLI ([@udx/worker-deployment](https://www.npmjs.com/package/@udx/worker-deployment)). +Run the published image with a Worker service config mounted into the container: ```bash -npm install -g @udx/worker-deployment -``` - -2. Generate a config and edit `deploy.yml` for your app. - -```bash -worker config -``` - -3. Run the container. - -```bash -worker run +docker run --rm \ + -v "$(pwd)/src/examples/simple-server:/usr/src/app" \ + -v "$(pwd)/src/examples/simple-server/.config/worker:/home/udx/.config/worker:ro" \ + -p 8080:8080 \ + usabilitydynamics/udx-worker-nodejs:latest ``` ## Usage -- Deploy configuration: https://github.com/udx/worker-deployment/blob/latest/docs/deploy-config.md +- Worker runtime config: https://github.com/udx/worker/blob/latest/docs/config.md + +- Service configuration: https://github.com/udx/worker/blob/latest/docs/services.md -- Service configuration: https://github.com/udx/worker/blob/latest/docs/runtime/services.md +- Runtime secrets: https://github.com/udx/worker/blob/latest/docs/secrets.md -- Runtime config and secrets: https://github.com/udx/worker/blob/latest/docs/runtime/config.md +- Local Worker config contract: [docs/worker-config.md](docs/worker-config.md) ### Examples @@ -67,7 +61,6 @@ Repo context generated by `dev.kit repo` lives in `.rabbit/context.yaml`; Rabbit ## Resources - Base image docs: https://github.com/udx/worker/tree/latest/docs -- Deployment CLI: https://github.com/udx/worker-deployment/tree/latest/docs - Docker Hub: https://hub.docker.com/r/usabilitydynamics/udx-worker-nodejs ## Contributing diff --git a/deploy.yml b/deploy.yml deleted file mode 100644 index 911b53b..0000000 --- a/deploy.yml +++ /dev/null @@ -1,19 +0,0 @@ -# npm install -g @udx/worker-deployment -# worker config -# worker run - ---- -kind: workerDeployConfig -version: udx.io/worker-v1/deploy -config: - image: "usabilitydynamics/udx-worker-nodejs:latest" - - # Volume mounts (optional) - # Format: "host_path:container_path" or "host_path:container_path:ro" - volumes: - - "./src/examples/simple-server:/usr/src/app" - - "./src/examples/simple-server/.config/worker:/home/udx/.config/worker:ro" - - # Ports to expose (optional) - ports: - - "8080:8080" diff --git a/docs/worker-config.md b/docs/worker-config.md new file mode 100644 index 0000000..43f965a --- /dev/null +++ b/docs/worker-config.md @@ -0,0 +1,51 @@ +# Worker Config + +`worker.yaml` is the checked-in Worker runtime config contract for this image. +Use it for image-level defaults and secret references that should travel with +the repo. Runtime platform values still win when the container is deployed. + +## Shape + +```yaml +kind: workerConfig +version: udx.io/worker-v1/config +config: + env: + APP_ENV: production + secrets: + DATABASE_URL: + from: database-url +``` + +Keep `config.env` for non-sensitive defaults. Keep `config.secrets` for secret +references only, not literal secret values. + +## Local Validation + +Validate the manifest syntax before opening a PR: + +```bash +yq e '.' worker.yaml +``` + +Refresh generated repo context after changing `worker.yaml` or this reference: + +```bash +dev.kit repo +``` + +## Deployment Behavior + +Deployment is external to the worker container. Use the host-native tool for +the target environment: Docker, Docker Compose, Kubernetes, Rabbit CI, or the +CI/CD platform's deployment step. + +Mount `worker.yaml` and `services.yaml` through the target platform's normal +config and secret primitives. Keep image selection, volume mounts, ports, and +release behavior in the deployment platform, not in Worker runtime config. + +Base Worker references: + +- https://github.com/udx/worker/blob/latest/docs/config.md +- https://github.com/udx/worker/blob/latest/docs/secrets.md +- https://github.com/udx/worker/blob/latest/docs/deployment.md diff --git a/src/examples/README.md b/src/examples/README.md index 457cced..4dc6349 100644 --- a/src/examples/README.md +++ b/src/examples/README.md @@ -44,18 +44,14 @@ services: image: usabilitydynamics/udx-worker-nodejs:latest volumes: - ./simple-server:/usr/src/app - - ./simple-server/.config:/home/udx/.config + - ./simple-server/.config/worker:/home/udx/.config/worker:ro ports: - "8080:8080" ``` -3. Using worker-deployment: -```bash -npm install -g @udx/worker-deployment -cd src/examples -cp simple-server/deploy.yml deploy.yml -worker run -``` +3. For deployment targets, keep image selection, volumes, ports, and release + behavior in Docker, Docker Compose, Kubernetes, Rabbit CI, or the target + CI/CD platform. Keep Worker runtime process definitions in `services.yaml`. ## 📁 Directory Structure Each example follows this structure: diff --git a/src/examples/simple-server/deploy.yml b/src/examples/simple-server/deploy.yml deleted file mode 100644 index ed8f4e7..0000000 --- a/src/examples/simple-server/deploy.yml +++ /dev/null @@ -1,16 +0,0 @@ -# npm install -g @udx/worker-deployment -# worker config -# worker run - ---- -kind: workerDeployConfig -version: udx.io/worker-v1/deploy -config: - image: "usabilitydynamics/udx-worker-nodejs:latest" - - volumes: - - "./simple-server:/usr/src/app" - - "./simple-server/.config/worker:/home/udx/.config/worker:ro" - - ports: - - "8080:8080" diff --git a/worker.yaml b/worker.yaml new file mode 100644 index 0000000..433a71f --- /dev/null +++ b/worker.yaml @@ -0,0 +1,11 @@ +--- +# Worker runtime config contract. +# References: +# - https://github.com/udx/worker/blob/latest/docs/config.md +# - https://github.com/udx/worker/blob/latest/docs/secrets.md +# - https://github.com/udx/worker/blob/latest/docs/deployment.md +kind: workerConfig +version: udx.io/worker-v1/config +config: + env: {} + secrets: {} From 170487877c4bd78d18f63b2f36357e940a8fc518 Mon Sep 17 00:00:00 2001 From: Dmytro Smirnov Date: Wed, 8 Jul 2026 20:43:38 +0300 Subject: [PATCH 5/8] fix: handle dependency updater review feedback --- .../workflows/docker-dependency-updater.yml | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docker-dependency-updater.yml b/.github/workflows/docker-dependency-updater.yml index 08c3d9d..baa23ec 100644 --- a/.github/workflows/docker-dependency-updater.yml +++ b/.github/workflows/docker-dependency-updater.yml @@ -195,8 +195,13 @@ jobs: } ' "${DOCKERFILE}" > "${PROBE_DOCKERFILE}" + current_node_version="$(awk -F= '/^ARG NODE_VERSION=/ { print $2; exit }' "${DOCKERFILE}")" + current_node_major="${current_node_version%%.*}" + test -n "${current_node_major}" + node_version="$(curl --retry 5 --retry-all-errors --retry-delay 2 -fsSL https://nodejs.org/dist/index.json \ - | jq -r '[.[] | select(.lts != false)][0].version | ltrimstr("v")')" + | jq -r --arg major "${current_node_major}" \ + '[.[] | select(.lts != false) | .version | ltrimstr("v") | select(startswith($major + "."))][0]')" test -n "${node_version}" base_image="$(curl --retry 5 --retry-all-errors --retry-delay 2 -fsSL \ @@ -216,6 +221,15 @@ jobs: apt_packages=(xz-utils) + { + echo + echo "# Dependency probe keeps apt packages installed for dpkg-query." + echo "RUN set -ex && \\" + echo " apt-get update && \\" + echo " apt-get install -y --no-install-recommends ${apt_packages[*]} && \\" + echo " rm -rf /var/lib/apt/lists/*" + } >> "${PROBE_DOCKERFILE}" + docker build --pull --no-cache -f "${PROBE_DOCKERFILE}" \ -t "${PROBE_IMAGE}" . docker run -i --rm --entrypoint bash "${PROBE_IMAGE}" \ @@ -225,7 +239,7 @@ jobs: dpkg-query -W -f='${binary:Package}\t${Version}\n' "$@" EOF strategy_summary="Use the latest udx-worker release, latest Node.js " - strategy_summary="${strategy_summary}LTS release, and a no-pin apt " + strategy_summary="${strategy_summary}LTS release within the current major, and a no-pin apt " strategy_summary="${strategy_summary}probe for xz-utils." non_apt_path="${probe_dir}/non-apt.json" @@ -470,8 +484,6 @@ jobs: [ "${UPLOAD_COPILOT_SESSION}" = "true" ]; then echo "- Copilot session artifact: \`copilot-docker-dependency-session.md\`" fi - echo "- Build validation: repository Docker/CI workflows" - echo echo "## Diff" echo echo '```diff' @@ -510,7 +522,7 @@ jobs: - name: Create pull request id: create-pr if: steps.changes.outputs.changed == 'true' - uses: peter-evans/create-pull-request@v8 + uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 timeout-minutes: 5 with: token: ${{ secrets.DEPENDABOT_REVIEWER_TOKEN || secrets.GH_TOKEN || github.token }} From 44b2652be0b6d01eb279847018c721695ae5ed38 Mon Sep 17 00:00:00 2001 From: Dmytro Smirnov Date: Wed, 8 Jul 2026 20:44:59 +0300 Subject: [PATCH 6/8] fix: normalize worker release tags in updater --- .github/workflows/docker-dependency-updater.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-dependency-updater.yml b/.github/workflows/docker-dependency-updater.yml index baa23ec..e0ae104 100644 --- a/.github/workflows/docker-dependency-updater.yml +++ b/.github/workflows/docker-dependency-updater.yml @@ -208,7 +208,7 @@ jobs: -H "Authorization: Bearer ${GITHUB_TOKEN}" \ -H "X-GitHub-Api-Version: 2022-11-28" \ "https://api.github.com/repos/udx/worker/releases/latest" \ - | jq -r '.tag_name')" + | jq -r '.tag_name | ltrimstr("v")')" test -n "${base_image}" base_image_ref="usabilitydynamics/udx-worker:${base_image}" From ca2849d37b02b6165785d2b96e33aaabfa8f79e9 Mon Sep 17 00:00:00 2001 From: Dmytro Smirnov Date: Wed, 8 Jul 2026 21:03:50 +0300 Subject: [PATCH 7/8] docs: align worker config references --- README.md | 2 +- src/examples/README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3d65653..602c4cc 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ To run a single test: make run-test TEST_SCRIPT=10_validate_environment.sh ``` -Build defaults for contributors live in `Makefile.variables` (Node.js version, ports, build args). +Build defaults for contributors live in `Makefile.variables`; the Node.js version is pinned in the `Dockerfile` `NODE_VERSION` argument. Repo context generated by `dev.kit repo` lives in `.rabbit/context.yaml`; Rabbit-facing workflow notes live in `.rabbit/README.md`. diff --git a/src/examples/README.md b/src/examples/README.md index 4dc6349..cac53f7 100644 --- a/src/examples/README.md +++ b/src/examples/README.md @@ -31,7 +31,7 @@ services: ```bash docker run -d --name my-node-app \ -v $(pwd)/simple-server:/usr/src/app \ - -v $(pwd)/simple-server/.config:/home/udx/.config \ + -v $(pwd)/simple-server/.config/worker:/home/udx/.config/worker:ro \ -p 8080:8080 \ usabilitydynamics/udx-worker-nodejs:latest ``` @@ -73,6 +73,6 @@ When running the examples, two key volume mounts are required: 2. Worker Configuration: ``` - -v ./.config:/home/udx/.config + -v ./.config/worker:/home/udx/.config/worker:ro ``` Mounts the worker service configuration From fce955bb43cac5d3d671e2a4e4e5aa8cbe94d1d1 Mon Sep 17 00:00:00 2001 From: Dmytro Smirnov Date: Fri, 10 Jul 2026 12:22:11 +0300 Subject: [PATCH 8/8] docs: remove redundant docs scaffold --- docs/README.md | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 docs/README.md diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 7625253..0000000 --- a/docs/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Repository Docs - -Use this directory for durable, human-authored repo documentation. - -- Keep the root `README.md` as the entry point for what the repo is and how to work with it. -- Keep Rabbit-facing workflow notes in `.rabbit/README.md`. -- Treat `.rabbit/context.yaml` as generated evidence from `dev.kit repo`, not as hand-authored documentation.