From f05efc5a2168050e086f8ce1203fb2672af81a03 Mon Sep 17 00:00:00 2001 From: iHildy Date: Wed, 31 Dec 2025 09:32:03 -0600 Subject: [PATCH 1/2] chore: add opencode smoke workflow --- .github/workflows/opencode-smoke.yml | 115 +++++++++++++++++++++++++++ .github/workflows/publish.yml | 57 ++++++++++++- 2 files changed, 169 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/opencode-smoke.yml diff --git a/.github/workflows/opencode-smoke.yml b/.github/workflows/opencode-smoke.yml new file mode 100644 index 0000000..b32752f --- /dev/null +++ b/.github/workflows/opencode-smoke.yml @@ -0,0 +1,115 @@ +name: Opencode Smoke + +on: + workflow_dispatch: + inputs: + tag: + description: 'npm dist-tag to test' + required: true + default: next + timeout: + description: 'seconds to wait before considering opencode stable' + required: false + default: '20' + workflow_call: + inputs: + tag: + type: string + required: true + timeout: + type: number + required: false + default: 20 + +jobs: + smoke: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest] + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + + - name: Resolve plugin version + id: version + run: | + VERSION=$(npm view opencode-synced@${{ inputs.tag }} version) + if [ -z "$VERSION" ]; then + echo "No version found for tag: ${{ inputs.tag }}" + exit 1 + fi + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + + - name: Install opencode + env: + OPENCODE_INSTALL_DIR: ${{ runner.temp }}/opencode/bin + run: | + curl -fsSL https://opencode.ai/install | bash + echo "${OPENCODE_INSTALL_DIR}" >> "$GITHUB_PATH" + + - name: Configure clean opencode home + env: + OPENCODE_HOME: ${{ runner.temp }}/opencode-home + PLUGIN_VERSION: ${{ steps.version.outputs.version }} + run: | + export HOME="$OPENCODE_HOME" + export XDG_CONFIG_HOME="$HOME/.config" + export XDG_CACHE_HOME="$HOME/.cache" + export XDG_DATA_HOME="$HOME/.local/share" + export XDG_STATE_HOME="$HOME/.local/state" + + mkdir -p "$XDG_CONFIG_HOME/opencode" + cat > "$XDG_CONFIG_HOME/opencode/opencode.json" <> "$GITHUB_OUTPUT" + + CANDIDATE_TAG="next" + echo "Publishing candidate with tag: $CANDIDATE_TAG (requested: $TAG)" + mise run publish --tag "$CANDIDATE_TAG" + + - name: Resolve published version + id: version + run: | + VERSION=$(npm view opencode-synced@next version) + if [ -z "$VERSION" ]; then + echo "Failed to resolve version from npm tag: next" + exit 1 + fi + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + + smoke: + needs: publish + uses: ./.github/workflows/opencode-smoke.yml + with: + tag: next + timeout: 20 + + promote_latest: + needs: [publish, smoke] + if: needs.publish.outputs.requested_tag == 'latest' + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + steps: + - uses: actions/checkout@v4 + + - uses: jdx/mise-action@d6e32c1796099e0f1f3ac741c220a8b7eae9e5dd + with: + install: true + cache: true + experimental: true + + - name: Promote latest dist-tag + run: | + VERSION="${{ needs.publish.outputs.version }}" + if [ -z "$VERSION" ]; then + echo "Missing published version." + exit 1 + fi + + echo "Promoting opencode-synced@$VERSION to latest" + npm dist-tag add "opencode-synced@$VERSION" latest From 9131ce83e47a3e56d15c0e8a1c033c1284fd42f7 Mon Sep 17 00:00:00 2001 From: iHildy Date: Wed, 31 Dec 2025 09:40:45 -0600 Subject: [PATCH 2/2] chore: capture opencode smoke logs --- .github/workflows/opencode-smoke.yml | 40 ++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/.github/workflows/opencode-smoke.yml b/.github/workflows/opencode-smoke.yml index b32752f..271076f 100644 --- a/.github/workflows/opencode-smoke.yml +++ b/.github/workflows/opencode-smoke.yml @@ -10,7 +10,7 @@ on: timeout: description: 'seconds to wait before considering opencode stable' required: false - default: '20' + default: '30' workflow_call: inputs: tag: @@ -19,7 +19,7 @@ on: timeout: type: number required: false - default: 20 + default: 30 jobs: smoke: @@ -75,6 +75,7 @@ jobs: env: OPENCODE_HOME: ${{ runner.temp }}/opencode-home OPENCODE_SMOKE_TIMEOUT: ${{ inputs.timeout }} + OPENCODE_SMOKE_LOG: ${{ runner.temp }}/opencode-smoke.log run: | export HOME="$OPENCODE_HOME" export XDG_CONFIG_HOME="$HOME/.config" @@ -84,11 +85,13 @@ jobs: python - <<'PY' import os + import threading import subprocess import time import sys timeout = int(os.environ.get("OPENCODE_SMOKE_TIMEOUT", "20")) + log_path = os.environ.get("OPENCODE_SMOKE_LOG", "opencode-smoke.log") cmd = ["opencode", "serve", "--port", "4096", "--hostname", "127.0.0.1"] proc = subprocess.Popen( @@ -98,12 +101,32 @@ jobs: text=True, ) - time.sleep(timeout) + def reader(): + if not proc.stdout: + return + with open(log_path, "w") as log_file: + for line in proc.stdout: + log_file.write(line) + + thread = threading.Thread(target=reader, daemon=True) + thread.start() + + start = time.time() + while time.time() - start < timeout: + if proc.poll() is not None: + break + time.sleep(1) if proc.poll() is not None: - output = proc.stdout.read() if proc.stdout else "" print("opencode exited early with code", proc.returncode) - print(output) + try: + with open(log_path, "r") as log_file: + lines = log_file.readlines() + tail = "".join(lines[-200:]) + print("--- opencode output (tail) ---") + print(tail) + except FileNotFoundError: + print("No log output captured.") sys.exit(1) proc.terminate() @@ -113,3 +136,10 @@ jobs: proc.kill() proc.wait() PY + + - name: Upload opencode logs (on failure) + if: failure() + uses: actions/upload-artifact@v4 + with: + name: opencode-smoke-logs-${{ matrix.os }} + path: ${{ runner.temp }}/opencode-smoke.log