fix(heartbeat): follow the user language #3923
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release Artifacts | |
| on: | |
| pull_request: | |
| paths: | |
| - ".github/workflows/release-artifacts.yml" | |
| - "examples/release-artifacts-smoke.py" | |
| - "loopx/**" | |
| - "package.json" | |
| - "package-lock.json" | |
| - "pyproject.toml" | |
| - "setup.py" | |
| - "MANIFEST.in" | |
| - "apps/presentation/dashboard/**" | |
| - "scripts/chat_bundle.py" | |
| - "scripts/verify_installed_chat.py" | |
| - "README.md" | |
| - "scripts/release_artifacts.py" | |
| - "tsconfig.control-plane.json" | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: "Existing GitHub Release tag containing this release tooling" | |
| required: true | |
| type: string | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: release-artifacts-${{ github.event.release.tag_name || inputs.tag || github.ref }} | |
| cancel-in-progress: false | |
| jobs: | |
| build: | |
| if: github.repository == 'loopx-project/loopx' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| permissions: | |
| contents: read | |
| id-token: write | |
| attestations: write | |
| outputs: | |
| release-tag: ${{ steps.identity.outputs.release-tag }} | |
| steps: | |
| - name: Check out release source | |
| uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ github.event.release.tag_name || inputs.tag || github.sha }} | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.11" | |
| cache: pip | |
| - name: Set up the packaged TypeScript control-plane runtime | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: "24" | |
| - name: Resolve and validate release identity | |
| id: identity | |
| env: | |
| EVENT_RELEASE_TAG: ${{ github.event.release.tag_name }} | |
| INPUT_RELEASE_TAG: ${{ inputs.tag }} | |
| run: | | |
| set -euo pipefail | |
| release_tag="${EVENT_RELEASE_TAG:-${INPUT_RELEASE_TAG:-}}" | |
| if [[ -z "${release_tag}" ]]; then | |
| release_tag="$(python scripts/release_artifacts.py expected-tag)" | |
| fi | |
| python scripts/release_artifacts.py validate-tag "${release_tag}" | |
| source_date_epoch="$(git show -s --format=%ct HEAD)" | |
| echo "release-tag=${release_tag}" >> "${GITHUB_OUTPUT}" | |
| echo "RELEASE_TAG=${release_tag}" >> "${GITHUB_ENV}" | |
| echo "SOURCE_DATE_EPOCH=${source_date_epoch}" >> "${GITHUB_ENV}" | |
| echo "PYTHONHASHSEED=0" >> "${GITHUB_ENV}" | |
| - name: Build exact release frontend with previous delivery assets | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: python scripts/chat_bundle.py release-build --tag "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" | |
| - name: Install release build tools | |
| run: python -m pip install --disable-pip-version-check build==1.4.4 twine==6.2.0 | |
| - name: Build wheel and source distribution | |
| run: python -m build --sdist --wheel --outdir dist/packages | |
| - name: Normalize source distribution metadata | |
| run: >- | |
| python scripts/release_artifacts.py normalize-sdist | |
| --dist-dir dist/packages | |
| --source-date-epoch "${SOURCE_DATE_EPOCH}" | |
| - name: Validate package metadata | |
| run: python -m twine check dist/packages/* | |
| - name: Generate and verify checksums | |
| run: | | |
| set -euo pipefail | |
| python scripts/release_artifacts.py write-checksums \ | |
| --dist-dir dist/packages \ | |
| --output dist/SHA256SUMS | |
| python scripts/release_artifacts.py verify-checksums \ | |
| --dist-dir dist/packages \ | |
| --checksum-file dist/SHA256SUMS | |
| - name: Verify wheel in a clean environment | |
| run: | | |
| set -euo pipefail | |
| python -m venv "${RUNNER_TEMP}/loopx-wheel" | |
| "${RUNNER_TEMP}/loopx-wheel/bin/python" -m pip install \ | |
| --disable-pip-version-check \ | |
| --no-deps \ | |
| dist/packages/*.whl | |
| test "$("${RUNNER_TEMP}/loopx-wheel/bin/loopx" --version)" = \ | |
| "loopx ${RELEASE_TAG#v}" | |
| "${RUNNER_TEMP}/loopx-wheel/bin/python" - <<'PY' | |
| from loopx.control_plane.effect_program import SettlementIdentity | |
| from loopx.control_plane.effect_runtime import ( | |
| collect_effect_runtime_readiness, | |
| ) | |
| from loopx.control_plane.turn_driver.turn_journal_runtime import ( | |
| interpret_turn_journal_projection, | |
| write_turn_journal, | |
| ) | |
| from pathlib import Path | |
| from tempfile import TemporaryDirectory | |
| turn_key = "sha256:" + "a" * 64 | |
| journal_identity = SettlementIdentity( | |
| goal_id="fixture-goal", | |
| agent_id="fixture-agent", | |
| todo_id="fixture-todo", | |
| turn_instance_id=turn_key, | |
| ) | |
| journal = { | |
| "schema_version": "loopx_turn_journal_v0", | |
| "goal_id": "fixture-goal", | |
| "turn_key": turn_key, | |
| "status": "committed", | |
| "completed_phases": [ | |
| "host_execute", | |
| "typed_result", | |
| "validation", | |
| "durable_writeback", | |
| "quota_spend", | |
| "scheduler_apply", | |
| "scheduler_ack", | |
| ], | |
| "plan": { | |
| "turn_envelope": { | |
| "goal_id": "fixture-goal", | |
| "agent_id": "fixture-agent", | |
| "action": { | |
| "selected_todo": {"todo_id": "fixture-todo"}, | |
| }, | |
| }, | |
| "transaction": { | |
| "turn_key": turn_key, | |
| "settlement_plan": { | |
| "schema_version": "quota_settlement_plan_v1", | |
| "identity": journal_identity.as_dict(), | |
| }, | |
| }, | |
| }, | |
| } | |
| result = interpret_turn_journal_projection( | |
| journal, | |
| goal_id="fixture-goal", | |
| agent_id="fixture-agent", | |
| turn_key=turn_key, | |
| ) | |
| assert result["decision"] == "replay_legal", result | |
| assert result["effects"] == [], result | |
| identity = SettlementIdentity( | |
| goal_id="fixture-goal", | |
| agent_id="fixture-agent", | |
| todo_id="fixture-todo", | |
| turn_instance_id="fixture-turn", | |
| ) | |
| assert identity.effect_id == ( | |
| "fixture-goal:fixture-agent:fixture-todo:fixture-turn" | |
| ), identity | |
| readiness = collect_effect_runtime_readiness(deep=True) | |
| assert readiness["status"] == "ready", readiness | |
| assert readiness["semantic_probe"] == "passed", readiness | |
| with TemporaryDirectory() as temporary_directory: | |
| effect_id = journal_identity.effect_id | |
| writable_journal = { | |
| **journal, | |
| "status": "in_progress", | |
| "completed_phases": [], | |
| } | |
| committed = write_turn_journal( | |
| str(Path(temporary_directory) / "turn.json"), | |
| writable_journal, | |
| expected_effect_id=effect_id, | |
| ) | |
| assert committed["appended"] is True, committed | |
| assert committed["replayed"] is False, committed | |
| PY | |
| - name: Verify installed frontend and sdist rebuild | |
| run: | | |
| python scripts/verify_installed_chat.py --python "${RUNNER_TEMP}/loopx-wheel/bin/python" | |
| python -m pip wheel --no-deps dist/packages/*.tar.gz --wheel-dir "${RUNNER_TEMP}/sdist-wheel" | |
| "${RUNNER_TEMP}/loopx-wheel/bin/python" -m pip install --force-reinstall --no-deps "${RUNNER_TEMP}"/sdist-wheel/*.whl | |
| python scripts/verify_installed_chat.py --python "${RUNNER_TEMP}/loopx-wheel/bin/python" | |
| - name: Exercise the installed page in a real browser | |
| working-directory: apps/presentation/dashboard | |
| env: | |
| LOOPX_PYTHON_BIN: ${{ runner.temp }}/loopx-wheel/bin/python | |
| run: | | |
| ./node_modules/.bin/playwright install --with-deps chromium | |
| npm run smoke:personal-workspace-packaged | |
| - name: Verify wheel through the DSH managed-runtime install shape | |
| run: | | |
| set -euo pipefail | |
| target="${RUNNER_TEMP}/loopx-wheel-target" | |
| skills_dir="${RUNNER_TEMP}/loopx-wheel-target-skills" | |
| python -m pip install \ | |
| --disable-pip-version-check \ | |
| --no-deps \ | |
| --target "${target}" \ | |
| dist/packages/*.whl | |
| ( | |
| cd "${RUNNER_TEMP}" | |
| PYTHONPATH="${target}" python -m loopx.cli --format json \ | |
| workflow-skills --skills-dir "${skills_dir}" \ | |
| --host-surface deepseek-harness-native \ | |
| > "${RUNNER_TEMP}/loopx-wheel-target-inspect.json" | |
| ) | |
| python - "${RUNNER_TEMP}/loopx-wheel-target-inspect.json" <<'PY' | |
| import json | |
| from pathlib import Path | |
| import sys | |
| payload = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8")) | |
| assert payload["ok"] is True, payload | |
| assert payload["operation"] == "inspect", payload | |
| assert payload["host_surface"] == "deepseek-harness-native", payload | |
| assert payload["source"]["kind"] == "python_distribution", payload | |
| assert payload["install_required"] is True, payload | |
| PY | |
| export CODEX_HOME="${RUNNER_TEMP}/loopx-wheel-codex" | |
| skills_dir="${CODEX_HOME}/skills" | |
| "${RUNNER_TEMP}/loopx-wheel/bin/loopx" --format json \ | |
| workflow-skills --install --skills-dir "${skills_dir}" \ | |
| > "${RUNNER_TEMP}/loopx-workflow-skills-install.json" | |
| "${RUNNER_TEMP}/loopx-wheel/bin/python" - \ | |
| "${RUNNER_TEMP}/loopx-workflow-skills-install.json" <<'PY' | |
| import json | |
| from pathlib import Path | |
| import sys | |
| payload = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8")) | |
| assert payload["ok"] is True, payload | |
| assert payload["source"]["kind"] == "python_distribution", payload | |
| assert payload["after"]["ready"] is True, payload | |
| PY | |
| conflicting_bin="${RUNNER_TEMP}/loopx-conflicting-bin" | |
| mkdir -p "${conflicting_bin}" | |
| ln -s /usr/bin/false "${conflicting_bin}/loopx" | |
| PATH="${conflicting_bin}:${PATH}" \ | |
| "${RUNNER_TEMP}/loopx-wheel/bin/loopx" --format json \ | |
| doctor --deep > "${RUNNER_TEMP}/loopx-wheel-doctor.json" | |
| "${RUNNER_TEMP}/loopx-wheel/bin/python" - \ | |
| "${RUNNER_TEMP}/loopx-wheel-doctor.json" <<'PY' | |
| import json | |
| from pathlib import Path | |
| import sys | |
| payload = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8")) | |
| assert payload["ok"] is True, payload | |
| assert payload["package"]["install_kind"] == "python_distribution", payload | |
| assert payload["path"]["loopx"] != payload["path"]["current_invocation"] | |
| validation = payload["release_candidate"] | |
| checks = {item["id"]: item for item in validation["checks"]} | |
| assert validation["schema_version"] == "loopx_python_distribution_checks_v0" | |
| assert checks["command_package_same_distribution"]["ok"] is True, payload | |
| assert checks["representative_distribution_paths"]["ok"] is True, payload | |
| assert "scripts/loopx" not in validation["representative_cli"][ | |
| "package_paths" | |
| ]["required"] | |
| PY | |
| "${RUNNER_TEMP}/loopx-wheel/bin/loopx" --format json \ | |
| workflow-skills --uninstall --skills-dir "${skills_dir}" \ | |
| > "${RUNNER_TEMP}/loopx-workflow-skills-uninstall.json" | |
| "${RUNNER_TEMP}/loopx-wheel/bin/python" - \ | |
| "${RUNNER_TEMP}/loopx-workflow-skills-uninstall.json" <<'PY' | |
| import json | |
| from pathlib import Path | |
| import sys | |
| payload = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8")) | |
| assert payload["ok"] is True, payload | |
| assert sorted(payload["result"]["removed"]) == [ | |
| "loopx", | |
| "loopx-benchmark", | |
| "loopx-doc-registry", | |
| "loopx-pr-program", | |
| "loopx-pr-review", | |
| "loopx-project", | |
| "loopx-self-repair", | |
| ], payload | |
| PY | |
| - name: Exercise release contract smoke | |
| run: python examples/release-artifacts-smoke.py | |
| - name: Attest release packages and checksum manifest | |
| if: github.event_name != 'pull_request' | |
| uses: actions/attest@v4 | |
| with: | |
| subject-path: | | |
| dist/packages/* | |
| dist/SHA256SUMS | |
| - name: Upload validated release bundle | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: loopx-${{ steps.identity.outputs.release-tag }} | |
| path: dist | |
| if-no-files-found: error | |
| retention-days: 30 | |
| upload-release: | |
| if: github.event_name != 'pull_request' | |
| needs: build | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Check out release source | |
| uses: actions/checkout@v7 | |
| with: | |
| ref: ${{ needs.build.outputs.release-tag }} | |
| - name: Download validated release bundle | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: loopx-${{ needs.build.outputs.release-tag }} | |
| path: dist | |
| - name: Verify checksums before upload | |
| run: >- | |
| python scripts/release_artifacts.py verify-checksums | |
| --dist-dir dist/packages | |
| --checksum-file dist/SHA256SUMS | |
| - name: Upload immutable GitHub Release assets | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| RELEASE_TAG: ${{ needs.build.outputs.release-tag }} | |
| run: | | |
| set -euo pipefail | |
| gh release view "${RELEASE_TAG}" --repo "${GITHUB_REPOSITORY}" >/dev/null | |
| gh release upload "${RELEASE_TAG}" \ | |
| dist/packages/* \ | |
| dist/SHA256SUMS \ | |
| --repo "${GITHUB_REPOSITORY}" | |
| publish-pypi: | |
| if: >- | |
| github.event_name != 'pull_request' && | |
| vars.PYPI_PUBLISH_ENABLED == 'true' | |
| needs: | |
| - build | |
| - upload-release | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| permissions: | |
| id-token: write | |
| environment: | |
| name: pypi | |
| url: https://pypi.org/project/loopx/ | |
| steps: | |
| - name: Download validated release bundle | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: loopx-${{ needs.build.outputs.release-tag }} | |
| path: dist | |
| - name: Publish distributions with PyPI Trusted Publishing | |
| uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1 | |
| with: | |
| packages-dir: dist/packages | |
| - name: Verify the published package from PyPI | |
| env: | |
| RELEASE_TAG: ${{ needs.build.outputs.release-tag }} | |
| run: | | |
| set -euo pipefail | |
| version="${RELEASE_TAG#v}" | |
| verify_target="${RUNNER_TEMP}/loopx-pypi-target-${version}" | |
| skills_dir="${RUNNER_TEMP}/loopx-pypi-skills-${version}" | |
| for attempt in {1..12}; do | |
| if python -m pip install \ | |
| --disable-pip-version-check \ | |
| --index-url https://pypi.org/simple \ | |
| --no-cache-dir \ | |
| --no-deps \ | |
| --target "${verify_target}" \ | |
| "loopx==${version}"; then | |
| if ( | |
| cd "${RUNNER_TEMP}" | |
| test "$(PYTHONPATH="${verify_target}" python -m loopx.cli --version)" = \ | |
| "loopx ${version}" | |
| PYTHONPATH="${verify_target}" python -m loopx.cli --format json \ | |
| workflow-skills --install --skills-dir "${skills_dir}" \ | |
| --host-surface deepseek-harness-native \ | |
| > "${RUNNER_TEMP}/loopx-pypi-workflow-skills.json" | |
| ); then | |
| python - "${RUNNER_TEMP}/loopx-pypi-workflow-skills.json" <<'PY' | |
| import json | |
| from pathlib import Path | |
| import sys | |
| payload = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8")) | |
| assert payload["ok"] is True, payload | |
| assert payload["operation"] == "install", payload | |
| assert payload["host_surface"] == "deepseek-harness-native", payload | |
| assert payload["source"]["kind"] == "python_distribution", payload | |
| assert payload["after"]["ready"] is True, payload | |
| PY | |
| exit 0 | |
| fi | |
| fi | |
| if [[ "${attempt}" -eq 12 ]]; then | |
| break | |
| fi | |
| echo "PyPI has not exposed loopx ${version} yet; retrying in 10 seconds" | |
| sleep 10 | |
| done | |
| echo "loopx ${version} is still not installable from PyPI" >&2 | |
| exit 1 |