From 272a9b44e796eb1072ea14026f87180a33e1d07a Mon Sep 17 00:00:00 2001 From: David de Hilster Date: Fri, 23 Oct 2026 11:39:11 -0400 Subject: [PATCH] New engine and language server versions arrive as pull requests Dependabot proposes each new NLPPlus for studio/server/requirements.txt, and the Language server workflow rebuilds browserServer.js from each new vscode-nlp release and opens a pull request for it. The Studio workflow tests both; merging and deploying stay by hand. Co-Authored-By: Claude Opus 5.5 --- .github/dependabot.yml | 19 ++++ .github/workflows/language-server.yml | 114 ++++++++++++++++++++++++ studio/public/language-server/SOURCE.md | 7 +- studio/server/requirements.txt | 3 +- 4 files changed, 139 insertions(+), 4 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/language-server.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..ad3a054 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,19 @@ +# Proposes new engine versions for the studio app (studio/server/requirements.txt pins +# NLPPlus). Dependabot opens a pull request; the Studio workflow tests it with the new +# engine; merging it, and the git pull and update.sh on the server, stay by hand. +# +# Only NLPPlus: the run server has no other dependency, and the page's npm packages are +# left alone here. + +version: 2 +updates: + - package-ecosystem: pip + directory: /studio/server + schedule: + interval: weekly + day: monday + allow: + - dependency-name: NLPPlus + commit-message: + prefix: "Engine:" + open-pull-requests-limit: 1 diff --git a/.github/workflows/language-server.yml b/.github/workflows/language-server.yml new file mode 100644 index 0000000..629d339 --- /dev/null +++ b/.github/workflows/language-server.yml @@ -0,0 +1,114 @@ +# Propose a new language server for the studio app when vscode-nlp releases. +# +# studio/public/language-server/browserServer.js is committed, built from a vscode-nlp +# tag named in SOURCE.md next to it. When a newer vscode-nlp release exists, this builds +# browserServer.js from it and opens a pull request; the Studio workflow tests that +# pull request. Merging it, and the git pull and update.sh on the server, stay by hand. +# (Engine versions are proposed the same way by Dependabot; see ../dependabot.yml.) +# +# GitHub-hosted runner ONLY -- never the self-hosted production runner +# (see deploy-studio.yml). Triggers are dispatch and schedule only. +# +# The pull request is opened with CLASSIC_PAT, not GITHUB_TOKEN: a pull request that +# GITHUB_TOKEN opens or pushes to starts no workflows, so it would arrive untested. + +name: Language server + +on: + # vscode-nlp pings this repository after every release (stopgap/deploy/workflows/ + # vscode-nlp.yml); deploy-studio.yml answers the same ping for the site root. + repository_dispatch: + types: [upstream-release] + + workflow_dispatch: + + # In case a ping is lost. Mondays 03:40 UTC. + schedule: + - cron: '40 3 * * 1' + +permissions: + contents: read + +concurrency: + group: language-server + cancel-in-progress: false + +jobs: + bump: + name: Propose the latest vscode-nlp language server + if: ${{ github.event_name != 'repository_dispatch' || github.event.client_payload.source == 'vscode-nlp' }} + runs-on: ubuntu-latest + timeout-minutes: 15 + env: + SOURCE_MD: studio/public/language-server/SOURCE.md + steps: + - uses: actions/checkout@v4 + with: + token: ${{ secrets.CLASSIC_PAT }} + + - name: Is there a newer vscode-nlp? + id: want + env: + GH_TOKEN: ${{ github.token }} + run: | + set -euo pipefail + tag="$(gh api repos/VisualText/vscode-nlp/releases/latest --jq .tag_name)" + branch="bump/language-server-$tag" + echo "latest vscode-nlp release: $tag" + if grep -qF "tag \`$tag\`" "$SOURCE_MD"; then + echo "browserServer.js is already built from $tag" + echo "go=false" >> "$GITHUB_OUTPUT" + elif git ls-remote --exit-code --heads origin "$branch" >/dev/null; then + echo "$branch already exists -- its pull request is waiting" + echo "go=false" >> "$GITHUB_OUTPUT" + else + echo "go=true" >> "$GITHUB_OUTPUT" + fi + echo "tag=$tag" >> "$GITHUB_OUTPUT" + echo "branch=$branch" >> "$GITHUB_OUTPUT" + + - uses: actions/checkout@v4 + if: steps.want.outputs.go == 'true' + with: + repository: VisualText/vscode-nlp + ref: ${{ steps.want.outputs.tag }} + path: _vscode-nlp + persist-credentials: false + + - uses: actions/setup-node@v4 + if: steps.want.outputs.go == 'true' + with: + node-version: "20" + + - name: Build browserServer.js + if: steps.want.outputs.go == 'true' + working-directory: _vscode-nlp + run: | + npm ci --no-audit --no-fund + npx webpack --mode production --config-name browserServer + + - name: Open the pull request + if: steps.want.outputs.go == 'true' + env: + GH_TOKEN: ${{ secrets.CLASSIC_PAT }} + TAG: ${{ steps.want.outputs.tag }} + BRANCH: ${{ steps.want.outputs.branch }} + run: | + set -euo pipefail + commit="$(git -C _vscode-nlp rev-parse --short=8 HEAD)" + cp _vscode-nlp/dist/browserServer.js studio/public/language-server/ + sed -i -E "s/tag \`[^\`]+\` \(\`[0-9a-f]+\`\)/tag \`$TAG\` (\`$commit\`)/" "$SOURCE_MD" + grep -qF "tag \`$TAG\`" "$SOURCE_MD" || { echo "could not update $SOURCE_MD"; exit 1; } + rm -rf _vscode-nlp + + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git switch -c "$BRANCH" + git add studio/public/language-server + git commit -m "Language server: vscode-nlp $TAG" + git push origin "$BRANCH" + gh pr create --base main --head "$BRANCH" \ + --title "Language server: vscode-nlp $TAG" \ + --body "browserServer.js rebuilt from vscode-nlp \`$TAG\` (\`$commit\`), by the Language server workflow ($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID). + + Check before merging: the Studio tests pass, and the page still sends what the server expects (\`nlp/workspaceFiles\`, \`nlp/telemetry\` in vscode-nlp's src/server/browserServer.ts). After merging, \`git pull\` and \`studio/deploy/update.sh\` on the server put it live." diff --git a/studio/public/language-server/SOURCE.md b/studio/public/language-server/SOURCE.md index 111f949..9944b13 100644 --- a/studio/public/language-server/SOURCE.md +++ b/studio/public/language-server/SOURCE.md @@ -8,8 +8,9 @@ server. The page sends it the analyzer's files with the `nlp/workspaceFiles` notification; see `src/server/browserServer.ts` and `memoryFiles.ts` in that repository. -**Committed, not built here.** Building it needs a vscode-nlp checkout and its npm -install. To update, in a vscode-nlp checkout: +**Committed, not built here.** When vscode-nlp releases, the Language server workflow +(`.github/workflows/language-server.yml`) builds it from the new tag and opens a pull +request. To update by hand, in a vscode-nlp checkout: ```bash npm ci @@ -17,4 +18,4 @@ npx webpack --mode production --config-name browserServer cp dist/browserServer.js ../nlp-studio/studio/public/language-server/ ``` -Then change the commit above. +Then change the tag and commit above; the workflow finds them there. diff --git a/studio/server/requirements.txt b/studio/server/requirements.txt index 28f68c6..5dca038 100644 --- a/studio/server/requirements.txt +++ b/studio/server/requirements.txt @@ -1,6 +1,7 @@ # The run server is standard-library Python; the engine is its one dependency. # -# Pinned, so a new engine reaches the studio only when it is bumped here. It must +# Pinned, so a new engine reaches the studio only when it is bumped here; Dependabot +# proposes each new NLPPlus as a pull request (.github/dependabot.yml). It must # stay at 2.2.38 or later: that is the first with nlp-engine 4.1.3, whose openfile() # creates the file it names on Linux (VisualText/nlp-engine#742). readfile() and # callconcept() arrived after 2.2.8 and 2.2.23, and the analyzers and templates the