Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
189 changes: 88 additions & 101 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -511,18 +511,59 @@ jobs:
# One publish per platform-specific VSIX. vsce requires a separate
# publish call for each --target platform; globbing all into one
# publish silently uses only the first.
# Same hardening as the Open VSX step, for the same reason: an
# unguarded loop under `set -e` aborts on the first failure and
# strands every target behind it. Retry with backoff, treat an
# already-published version as done so re-runs are safe, and try
# every target before failing. An expired PAT is NOT retried — it
# can only fail again, so it exits immediately with the fix.
shopt -s globstar nullglob
published=0
skipped=0
failed=()
for vsix in **/*.vsix; do
echo "Publishing $vsix"
npx --yes @vscode/vsce publish $flag --packagePath "$vsix"
published=$((published + 1))
attempt=1
delay=15
while :; do
set +e
out="$(npx --yes @vscode/vsce publish $flag --packagePath "$vsix" 2>&1)"
rc=$?
set -e
echo "$out"
if [ "$rc" -eq 0 ]; then
published=$((published + 1))
break
fi
if grep -qiE 'already exists|greater than .* version' <<<"$out"; then
echo "$vsix is already published at this version — nothing to do"
skipped=$((skipped + 1))
break
fi
if grep -qi 'Personal Access Token used has expired' <<<"$out"; then
echo "::error::VSCODE_MARKETPLACE_PAT has EXPIRED. Mint a new Azure DevOps PAT at https://aka.ms/vscodepat — Organization: 'All accessible organizations', Scope: Marketplace → Manage — and update the Nimblesite org secret VSCODE_MARKETPLACE_PAT. Retrying cannot help."
exit 1
fi
if [ "$attempt" -ge 4 ]; then
echo "::warning::$vsix still failing after $attempt attempts"
failed+=("$vsix")
break
fi
echo "Attempt $attempt failed (exit $rc); retrying in ${delay}s"
sleep "$delay"
attempt=$((attempt + 1))
delay=$((delay * 2))
done
done
if [ "$published" -eq 0 ]; then
if [ "$((published + skipped))" -eq 0 ] && [ "${#failed[@]}" -eq 0 ]; then
echo "::error::No VSIX artifacts found to publish"
exit 1
fi
echo "Published $published VSIX(es) to the Marketplace"
echo "Marketplace: $published published, $skipped already present, ${#failed[@]} failed"
if [ "${#failed[@]}" -gt 0 ]; then
echo "::error::Marketplace publish failed for: ${failed[*]}"
exit 1
fi

publish-vsix-ovsx:
name: Publish VSIX (Open VSX)
Expand Down Expand Up @@ -574,18 +615,57 @@ jobs:
# ovsx is version-pinned: a floating `npx ovsx` would fetch and run
# the latest release at publish time, inside the job that holds the
# token — a supply-chain risk. Bump deliberately.
# Open VSX returns transient 5xx under load. v0.41.0 published three
# targets, took a 503 on the fourth, and `set -e` aborted the loop —
# leaving win32-arm64 and win32-x64 unpublished with no retry. So:
# retry each target with backoff, treat "already exists" as the
# desired end state (makes re-runs and partial retries safe), and
# attempt EVERY target before failing, so one bad target can never
# strand the ones behind it. The job still fails if any target is
# ultimately unpublished — a partial push is never reported as green.
shopt -s globstar nullglob
published=0
skipped=0
failed=()
for vsix in **/*.vsix; do
echo "Publishing $vsix"
npx --yes ovsx@1.0.0 publish $flag --packagePath "$vsix"
published=$((published + 1))
attempt=1
delay=15
while :; do
set +e
out="$(npx --yes ovsx@1.0.0 publish $flag --packagePath "$vsix" 2>&1)"
rc=$?
set -e
echo "$out"
if [ "$rc" -eq 0 ]; then
published=$((published + 1))
break
fi
if grep -qi 'already exists' <<<"$out"; then
echo "$vsix is already published at this version — nothing to do"
skipped=$((skipped + 1))
break
fi
if [ "$attempt" -ge 4 ]; then
echo "::warning::$vsix still failing after $attempt attempts"
failed+=("$vsix")
break
fi
echo "Attempt $attempt failed (exit $rc); retrying in ${delay}s"
sleep "$delay"
attempt=$((attempt + 1))
delay=$((delay * 2))
done
done
if [ "$published" -eq 0 ]; then
if [ "$((published + skipped))" -eq 0 ] && [ "${#failed[@]}" -eq 0 ]; then
echo "::error::No VSIX artifacts found to publish"
exit 1
fi
echo "Published $published VSIX(es) to Open VSX"
echo "Open VSX: $published published, $skipped already present, ${#failed[@]} failed"
if [ "${#failed[@]}" -gt 0 ]; then
echo "::error::Open VSX publish failed for: ${failed[*]}"
exit 1
fi

deploy-pages:
name: Deploy GitHub Pages
Expand Down Expand Up @@ -721,99 +801,6 @@ jobs:
git push origin "${GITHUB_REF_NAME}"
fi

publish-zed:
name: Publish Zed extension
needs: release
runs-on: ubuntu-latest
timeout-minutes: 15
if: startsWith(github.ref, 'refs/tags/')
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

# The zed-industries/extensions registry compiles the extension to WASM
# standalone, so the mirror must build outside the monorepo. Gate the push
# on that exact build here — never publish a tree the registry cannot
# compile. Same target the `zed` CI job uses ([ZED-MIRROR]).
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
with:
targets: wasm32-wasip2

- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
key: release-zed-wasm
cache-on-failure: true

- name: Render standalone Zed extension and push to the basilisk-zed mirror
# Same write convention as publish-nvim: clone the sibling Nimblesite/*
# repo with the x-access-token credential, replace its content, then
# commit as github-actions[bot] and push. Unlike the nvim plugin, the
# Zed crate carries the 0.0.0-PLACEHOLDER version and a workspace path
# dep on basilisk-common, so it cannot be pinned or built by the registry
# as-is. render-zed-mirror.sh vendors basilisk-common, stamps the
# version, and emits a self-contained tree; the WASM build below gates
# the push. The PAT must be able to write to Nimblesite/basilisk-zed.
env:
BREW_SCOOP_PAT: ${{ secrets.BREW_SCOOP_PAT }}
run: |
set -euo pipefail
if [ -z "${BREW_SCOOP_PAT:-}" ]; then
echo "::error::BREW_SCOOP_PAT not accessible. The Nimblesite org secret exists; ensure Basilisk is in its allowed repositories AND that the token can write to Nimblesite/basilisk-zed (Org Settings → Secrets and variables → Actions → BREW_SCOOP_PAT → Repository access)."
exit 1
fi

export BASILISK_VERSION="${GITHUB_REF_NAME#v}"

# Render into a staging tree, then prove it builds standalone before
# anything is pushed. cargo build also writes the Cargo.lock that the
# registry uses for a reproducible build, so commit the generated lock.
scripts/render-zed-mirror.sh staging "${BASILISK_VERSION}"
( cd staging && cargo build --release --target wasm32-wasip2 )

git clone "https://x-access-token:${BREW_SCOOP_PAT}@github.com/Nimblesite/basilisk-zed.git" mirror

# Replace the mirror's tracked content with the rendered tree,
# preserving the mirror's own .git. The build's target/ dir is large
# and machine-specific — never publish it.
rm -rf staging/target
find mirror -mindepth 1 -maxdepth 1 ! -name .git -exec rm -rf {} +
cp -R staging/. mirror/

cd mirror
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add -A
if git diff --cached --quiet; then
echo "basilisk-zed already up to date for ${BASILISK_VERSION}"
else
git commit -m "basilisk ${BASILISK_VERSION}"
git push
fi

# Tag the mirror with the SAME tag as the monorepo. The registry pins a
# commit; the tag gives the registry PR a stable, human-readable ref
# and keeps the extension version and the binary that resolve_binary
# auto-downloads from Nimblesite/Basilisk releases identical.
# Idempotent: skip if the tag already exists.
if git ls-remote --exit-code --tags origin "refs/tags/${GITHUB_REF_NAME}" >/dev/null 2>&1; then
echo "Tag ${GITHUB_REF_NAME} already present on the mirror"
else
git tag "${GITHUB_REF_NAME}"
git push origin "${GITHUB_REF_NAME}"
fi

# Pushing the mirror publishes NOTHING on its own — Zed installs only what
# zed-industries/extensions lists. That listing was a manual to-do nobody
# ever did, which is why Basilisk has never appeared in Zed's extensions
# view. This step performs it: first release opens the PR, later releases
# move the submodule pointer and version on the same branch. Idempotent —
# a re-run with nothing to change is a no-op. See [ZED-MIRROR].
- name: Submit or bump the zed-industries/extensions listing
env:
GH_TOKEN: ${{ secrets.BREW_SCOOP_PAT }}
run: |
set -euo pipefail
scripts/publish_zed_registry.py "${GITHUB_REF_NAME#v}" "${GITHUB_REF_NAME}"

publish-scoop:
name: Publish Scoop manifest
needs: release
Expand Down
5 changes: 1 addition & 4 deletions README-pypi.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,7 @@ instead of implementing the typing specification generally: rules that matched
the *spelling* of code rather than its meaning. Rename an import or reformat a
file and the answer changed. A score produced that way is not evidence.

**This was a mistake and a failure to verify — not an attempt to game the suite.**
Nobody set out to defeat the conformance tests, and nothing was concealed from
`python/typing`: the submission ran the suite's own unmodified harness, with
default configuration and every rule enabled. Our process treated the score as
**This was a mistake and a failure to verify.** Our process treated the score as
the goal, matching text raises a score faster than real analysis does, and we
published without ever asking whether a rule still held when the same program was
spelled differently. Basilisk's author has published a
Expand Down
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,7 @@ instead of implementing the typing specification generally: rules that matched
the *spelling* of code rather than its meaning. Rename an import or reformat a
file and the answer changed. A score produced that way is not evidence.

**This was a mistake and a failure to verify — not an attempt to game the suite.**
Nobody set out to defeat the conformance tests, and nothing was concealed from
`python/typing`: the submission ran the suite's own unmodified harness, with
default configuration and every rule enabled. Our process treated the score as
**This was a mistake and a failure to verify.** Our process treated the score as
the goal, matching text raises a score faster than real analysis does, and we
published without ever asking whether a rule still held when the same program was
spelled differently. Basilisk's author has published a
Expand Down
4 changes: 1 addition & 3 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@
那些规则匹配的是代码的**写法**,而不是代码的含义。改一个导入别名或重新格式化文件,
结论就会变。这样得出的分数并不能作为证据。

**这是一个错误、一次验证上的失职,而不是有意操纵测试套件。** 没有人试图去糊弄一致性
测试,也没有向 `python/typing` 隐瞒任何东西:提交时运行的是套件自己未经修改的评分
工具,使用默认配置并启用全部规则。我们的流程把分数当成了目标,而匹配文本比真正做
**这是一个错误、一次验证上的失职。** 我们的流程把分数当成了目标,而匹配文本比真正做
分析更快地提高分数;我们在发布之前,始终没有问过这样一个问题 —— 同一个程序换一种
写法时,这条规则是否依然成立。Basilisk 作者已发表
[个人说明与致歉](https://www.christianfindlay.com/blog/basilisk-conformance-apology)。
Expand Down
2 changes: 1 addition & 1 deletion basilisk-zed/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Basilisk is an open-source Python type checker and language server built in Rust
>
> **The type checker still contains code that isn't doing real type checking, and it is not yet trustworthy.** Some rules decide from the way code is *spelled* rather than what it means, so they can be wrong in both directions — a false error on correct code, or silence where there is a genuine bug. Don't gate CI on it, and don't read a clean run as a clean codebase. Our former conformance claim and our benchmark figures are withdrawn, and Basilisk was [removed from the official results](https://github.com/python/typing/blob/main/conformance/results/results.html) at our request.
>
> **This was a mistake and a failure to verify — not an attempt to game the suite.** Nothing was concealed from `python/typing`; the submission ran the suite's own unmodified harness, and we published on a green run without ever checking whether our rules survived a semantics-preserving change. Basilisk's author has published a [personal account and apology](https://www.christianfindlay.com/blog/basilisk-conformance-apology).
> **This was a mistake and a failure to verify.** We published on a green run without ever checking whether our rules survived a semantics-preserving change. Basilisk's author has published a [personal account and apology](https://www.christianfindlay.com/blog/basilisk-conformance-apology).
>
> **We are auditing every rule and deleting the ones that don't hold up** — not rewriting them, not patching them, with a failing test left behind so the gap stays visible. Where a rule can't be made reliable in a straightforward way, we will depend on a different, established type checker rather than ship our own unreliable version of it.
>
Expand Down
2 changes: 1 addition & 1 deletion basilisk-zed/README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Basilisk 是用 Rust 打造的开源 Python 类型检查器与语言服务器:
>
> **类型检查器中仍然存在没有做真正类型检查的代码,它目前还不值得信任。** 有些规则依据的是代码的**写法**而不是含义,因此两个方向上都可能出错 —— 既可能对正确的代码报出虚假错误,也可能对真实的缺陷保持沉默。请不要用它作为 CI 的门禁,也不要把一次干净的运行结果当作代码库是干净的。此前的一致性宣称与基准测试数字均已撤回,并主动请求[从官方结果中移除](https://github.com/python/typing/blob/main/conformance/results/results.html)。
>
> **这是一个错误、一次验证上的失职,而不是有意操纵测试套件。** 我们没有向 `python/typing` 隐瞒任何东西:提交时运行的是套件自己未经修改的评分工具;我们仅凭一次全绿的运行就发布了结果,却从未检查过我们的规则能否经受住保持语义的改写。Basilisk 作者已发表[个人说明与致歉](https://www.christianfindlay.com/blog/basilisk-conformance-apology)。
> **这是一个错误、一次验证上的失职。** 我们仅凭一次全绿的运行就发布了结果,却从未检查过我们的规则能否经受住保持语义的改写。Basilisk 作者已发表[个人说明与致歉](https://www.christianfindlay.com/blog/basilisk-conformance-apology)。
>
> **我们正在逐条审计规则,并删除那些站不住脚的规则** —— 不是重写,也不是打补丁,而是删除,并留下一个失败的测试,让缺口保持可见。如果一条规则无法以直截了当的方式做到可靠,我们会转而依赖另一个成熟的类型检查器,而不是端出我们自己那份不可靠的实现。
>
Expand Down
2 changes: 1 addition & 1 deletion basilisk.nvim/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Basilisk is an open-source Python type checker and language server built in Rust
>
> **The type checker still contains code that isn't doing real type checking, and it is not yet trustworthy.** Some rules decide from the way code is *spelled* rather than what it means, so they can be wrong in both directions — a false error on correct code, or silence where there is a genuine bug. Don't gate CI on it, and don't read a clean run as a clean codebase. Our former conformance claim and our benchmark figures are withdrawn, and Basilisk was [removed from the official results](https://github.com/python/typing/blob/main/conformance/results/results.html) at our request.
>
> **This was a mistake and a failure to verify — not an attempt to game the suite.** Nothing was concealed from `python/typing`; the submission ran the suite's own unmodified harness, and we published on a green run without ever checking whether our rules survived a semantics-preserving change. Basilisk's author has published a [personal account and apology](https://www.christianfindlay.com/blog/basilisk-conformance-apology).
> **This was a mistake and a failure to verify.** We published on a green run without ever checking whether our rules survived a semantics-preserving change. Basilisk's author has published a [personal account and apology](https://www.christianfindlay.com/blog/basilisk-conformance-apology).
>
> **We are auditing every rule and deleting the ones that don't hold up** — not rewriting them, not patching them, with a failing test left behind so the gap stays visible. Where a rule can't be made reliable in a straightforward way, we will depend on a different, established type checker rather than ship our own unreliable version of it.
>
Expand Down
Loading