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
7 changes: 7 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ on:
description: Build the VS Code extension.
type: boolean
default: true
extension-pre-release:
description: Mark the VSIX as a pre-release.
type: boolean
default: false
test-extension:
description: Run the VS Code extension test suites.
type: boolean
Expand Down Expand Up @@ -212,6 +216,9 @@ jobs:
if [ "${{ inputs.build-cli }}" != "true" ]; then
args+=(--skip-cli)
fi
if [ "${{ inputs.extension-pre-release }}" = "true" ]; then
args+=(--extension-pre-release)
fi
printf 'build-test-release %s\n' "${args[*]}"
./scripts/build-test-release "${args[@]}"

Expand Down
68 changes: 62 additions & 6 deletions .github/workflows/release-vscode.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# Releases the VS Code extension when a vscode-v* tag is pushed.
#
# package.json holds the version; the tag is validated against it. The Marketplace
# and Open VSX steps skip cleanly until their tokens are configured, so the
# workflow is usable for GitHub Releases before those accounts exist.
# package.json holds the version; the tag is validated against it. A `-pre` suffix
# on the tag publishes a pre-release: vscode-v0.0.2 is stable, vscode-v0.0.2-pre is
# not. The suffix lives on the tag rather than in the version because VS Code
# extension versions must stay major.minor.patch; what marks a pre-release is a
# property inside the package.
#
# The Marketplace and Open VSX steps skip cleanly until their tokens are
# configured, so the workflow is usable for GitHub Releases before that.

name: Release VS Code extension

Expand All @@ -23,23 +28,40 @@ jobs:
timeout-minutes: 5
outputs:
version: ${{ steps.check.outputs.version }}
pre-release: ${{ steps.check.outputs.pre-release }}
steps:
- uses: actions/checkout@v5

- id: check
run: |
manifest=$(node -p "require('./vscode-extension/package.json').version")
pre_release=false

if [ "${GITHUB_REF_TYPE}" = "tag" ]; then
tag_version="${GITHUB_REF_NAME#vscode-v}"
# A -pre suffix selects a pre-release and is not part of the version.
case "$tag_version" in
*-pre)
pre_release=true
tag_version="${tag_version%-pre}"
;;
esac

if [ "$tag_version" != "$manifest" ]; then
echo "Tag $GITHUB_REF_NAME implies version $tag_version," >&2
echo "but vscode-extension/package.json declares $manifest." >&2
echo "Bump package.json and package-lock.json, or retag." >&2
exit 1
fi
fi

echo "version=$manifest" >> "$GITHUB_OUTPUT"
echo "extension version $manifest" >> "$GITHUB_STEP_SUMMARY"
echo "pre-release=$pre_release" >> "$GITHUB_OUTPUT"
if [ "$pre_release" = "true" ]; then
echo "extension version $manifest (pre-release)" >> "$GITHUB_STEP_SUMMARY"
else
echo "extension version $manifest (stable)" >> "$GITHUB_STEP_SUMMARY"
fi

build:
needs: verify-version
Expand All @@ -51,6 +73,9 @@ jobs:
build-extension: true
test-extension: true
upload-artifacts: true
# Decided at build time: vsce refuses to publish a package as a pre-release
# unless the marker is already in its manifest.
extension-pre-release: ${{ needs.verify-version.outputs.pre-release == 'true' }}

publish:
name: Publish
Expand All @@ -61,6 +86,7 @@ jobs:
contents: write
env:
VERSION: ${{ needs.verify-version.outputs.version }}
PRE_RELEASE: ${{ needs.verify-version.outputs.pre-release }}
# Job-level so the publish steps' `if` expressions can test them.
VSCE_PAT: ${{ secrets.VSCE_PAT }}
OVSX_PAT: ${{ secrets.OVSX_PAT }}
Expand Down Expand Up @@ -94,17 +120,37 @@ jobs:
echo "Too few server plug-ins; the symlink did not resolve." >&2
exit 1
fi

# The marker is baked in at package time, so confirm the package matches
# what the tag asked for. vsce would reject a mismatch in one direction
# and silently publish a pre-release as stable in the other.
if unzip -p "$vsix" extension.vsixmanifest | grep -q 'Microsoft.VisualStudio.Code.PreRelease'; then
marked=true
else
marked=false
fi
echo "packaged as pre-release: $marked (tag asked for $PRE_RELEASE)"
if [ "$marked" != "$PRE_RELEASE" ]; then
echo "VSIX pre-release marker does not match the tag." >&2
exit 1
fi

echo "VSIX=$vsix" >> "$GITHUB_ENV"

- name: Create the GitHub release
if: github.ref_type == 'tag'
env:
GH_TOKEN: ${{ github.token }}
run: |
args=()
if [ "$PRE_RELEASE" = "true" ]; then
args+=(--prerelease)
fi
gh release create "$GITHUB_REF_NAME" \
--repo "$GITHUB_REPOSITORY" \
--title "AADL2 VS Code extension $VERSION" \
--generate-notes \
"${args[@]+"${args[@]}"}" \
"$VSIX"

- name: Install publishing tools
Expand All @@ -117,7 +163,12 @@ jobs:
- name: Publish to the VS Code Marketplace
if: github.ref_type == 'tag' && env.VSCE_PAT != ''
working-directory: vscode-extension
run: npx --no-install vsce publish --packagePath "../$VSIX"
run: |
args=()
if [ "$PRE_RELEASE" = "true" ]; then
args+=(--pre-release)
fi
npx --no-install vsce publish --packagePath "../$VSIX" "${args[@]+"${args[@]}"}"

# Requires the "osate" namespace claimed at open-vsx.org and its token
# stored as OVSX_PAT.
Expand All @@ -126,7 +177,12 @@ jobs:
working-directory: vscode-extension
# --yes because ovsx is not a devDependency, so npx must fetch it and
# would otherwise wait for a confirmation that never comes in CI.
run: npx --yes ovsx publish "../$VSIX" --pat "$OVSX_PAT"
run: |
args=()
if [ "$PRE_RELEASE" = "true" ]; then
args+=(--pre-release)
fi
npx --yes ovsx publish "../$VSIX" --pat "$OVSX_PAT" "${args[@]+"${args[@]}"}"

- name: Note skipped publications
if: github.ref_type == 'tag'
Expand Down
51 changes: 48 additions & 3 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ by pushing a component-prefixed tag; nothing is published from `main`.
| Component | Tag | Version source |
| --- | --- | --- |
| `osate-cli` | `osate-cli-v<version>` | `<revision>` in [`osate-cli/pom.xml`](osate-cli/pom.xml) |
| VS Code extension | `vscode-v<version>` | `version` in [`vscode-extension/package.json`](vscode-extension/package.json) |
| VS Code extension | `vscode-v<version>` or `vscode-v<version>-pre` | `version` in [`vscode-extension/package.json`](vscode-extension/package.json) |
| Language server | `ls-v<version>` | `aadl.ls.parent` version in [`aadl-language-server/pom.xml`](aadl-language-server/pom.xml) |

The tag does not set the version. Each release workflow reads the version out of
Expand All @@ -23,8 +23,8 @@ of truth. Bump the version in a normal commit first, then tag that commit.

# 2. Tag the merged commit and push the tag.
git switch main && git pull
git tag osate-cli-v0.1.4
git push origin osate-cli-v0.1.4
git tag osate-cli-v0.1.0
git push origin osate-cli-v0.1.0
```

Watch it with `gh run watch`. Each workflow also accepts `workflow_dispatch`,
Expand All @@ -49,6 +49,51 @@ Code Marketplace and Open VSX. The VSIX is checked for a plausible number of
bundled server plug-ins first, because the server reaches it through a symlink
that would otherwise fail silently.

### Stable or pre-release

A `-pre` suffix on the tag publishes a pre-release; without it the release is
stable. The version itself is identical either way:

```bash
git tag vscode-v0.1.0-pre # pre-release: users must opt in
git tag vscode-v0.1.0 # stable: offered to everyone
```

A pre-release is marked as such on the Marketplace and on Open VSX, and the
GitHub Release gets the pre-release badge. VS Code keeps users on the newest
*stable* version unless they explicitly switch that extension to the pre-release
channel, so this is the way to put a build in front of willing testers without
pushing it at everyone.

The suffix belongs on the tag rather than in the version because VS Code
extension versions must stay `major.minor.patch` — a pre-release is not a
different version string, it is a property recorded inside the package. That
property is written by `vsce package --pre-release`, and `vsce publish` **refuses**
to publish a package as a pre-release unless it was built as one:

```text
Cannot use '--pre-release' flag with a package that was not packaged as
pre-release. Please package it using the '--pre-release' flag and publish again.
```

So the decision is made at build time, not publish time. The tag drives it all
the way down: `release-vscode.yml` parses the suffix, passes
`extension-pre-release` to the build workflow, which passes
`--extension-pre-release` to `scripts/build-test-release`, which sets
`-Dvsce.package.script=package:pre-release` so Maven runs the npm script that adds
the flag. Before publishing, the workflow re-reads the built VSIX manifest and
fails if the marker disagrees with the tag, so the two cannot drift apart.

Marketplace and Open VSX both treat a published version as permanent — you can
unpublish an extension but not an individual version. Choosing pre-release does
not change that; it only changes who is offered the build.

To produce a pre-release VSIX locally:

```bash
./scripts/build-test-release --skip-osate --extension-pre-release
```

**`ls-v*`** — [`release-server.yml`](.github/workflows/release-server.yml)

The p2 repository archive plus `build-provenance.properties`, attached to a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: AADL Language Server
Bundle-SymbolicName: org.osate.aadl.ls;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Version: 0.1.0.qualifier
Bundle-Vendor: CMU-SEI
Automatic-Module-Name: org.osate.aadl.ls
Bundle-RequiredExecutionEnvironment: JavaSE-21
Expand Down
4 changes: 2 additions & 2 deletions aadl-language-server/org.osate.aadl.ls/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@
<parent>
<groupId>org.osate</groupId>
<artifactId>aadl.ls.parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>0.1.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>

<groupId>org.osate</groupId>
<artifactId>org.osate.aadl.ls</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>0.1.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: AADL Language Server Tests
Bundle-SymbolicName: org.osate.aadl.ls.tests;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Version: 0.1.0.qualifier
Bundle-Vendor: CMU-SEI
Fragment-Host: org.osate.aadl.ls
Automatic-Module-Name: org.osate.aadl.ls.tests
Expand Down
4 changes: 2 additions & 2 deletions aadl-language-server/plugins/org.osate.aadl.ls.tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@
<parent>
<groupId>org.osate</groupId>
<artifactId>aadl.ls.parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>0.1.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>

<groupId>org.osate</groupId>
<artifactId>org.osate.aadl.ls.tests</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>0.1.0-SNAPSHOT</version>
<packaging>eclipse-test-plugin</packaging>

<build>
Expand Down
2 changes: 1 addition & 1 deletion aadl-language-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
</parent>

<artifactId>aadl.ls.parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>0.1.0-SNAPSHOT</version>
<packaging>pom</packaging>

<repositories>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<parent>
<groupId>org.osate</groupId>
<artifactId>aadl.ls.parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>0.1.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion osate-cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
the tarball, deb, rpm, and Homebrew package versions.
Keep it a plain release version: rpm forbids '-' in Version, so a
'-SNAPSHOT' suffix would not survive packaging. -->
<revision>0.1.3</revision>
<revision>0.1.0</revision>
<maven.compiler.release>21</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<gson.version>2.11.0</gson.version>
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>org.osate</groupId>
<artifactId>aadl-language-server-aggregator</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>0.1.0-SNAPSHOT</version>
<packaging>pom</packaging>

<modules>
Expand Down
17 changes: 16 additions & 1 deletion scripts/build-test-release
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ skip_osate=false
skip_extension=false
skip_extension_tests=false
skip_cli=false
extension_pre_release=false

usage() {
cat <<'EOF'
Expand All @@ -57,6 +58,10 @@ Options:
integration tests download VS Code and need a
display, which is not always available.
--skip-cli Do not build the osate-cli reactor.
--extension-pre-release Mark the VSIX as a pre-release. vsce writes this into
the package manifest and refuses to publish a package
as a pre-release unless it was built as one, so this
has to be decided at build time.
-h, --help Show this help.
EOF
}
Expand All @@ -76,6 +81,9 @@ while [[ $# -gt 0 ]]; do
--skip-cli)
skip_cli=true
;;
--extension-pre-release)
extension_pre_release=true
;;
-h | --help)
usage
exit 0
Expand Down Expand Up @@ -174,12 +182,19 @@ mvn \
if [[ "${skip_extension}" == true ]]; then
echo "Skipping VS Code extension"
else
echo "Building VS Code extension"
extension_args=()
if [[ "${extension_pre_release}" == true ]]; then
echo "Building VS Code extension (pre-release)"
extension_args+=(-Dvsce.package.script=package:pre-release)
else
echo "Building VS Code extension"
fi

mvn \
-T6 \
-f "${repo_root}/vscode-extension/pom.xml" \
-Dtycho.localArtifacts=ignore \
"${extension_args[@]+"${extension_args[@]}"}" \
clean verify
fi

Expand Down
1 change: 1 addition & 0 deletions vscode-extension/.vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ src/**
.gitignore
.yarnrc
vsc-extension-quickstart.md
images/*.svg
**/tsconfig.json
**/tsconfig.test.json
**/.eslintrc.json
Expand Down
9 changes: 8 additions & 1 deletion vscode-extension/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,16 @@ tests.
Package the extension with:

```bash
npm run package
npm run package # stable
npm run package:pre-release # marked as a pre-release
```

The pre-release marker is written into the VSIX manifest at package time, and
`vsce publish` refuses to publish a package as a pre-release unless it was built
as one, so it cannot be added later. `vscode-extension/pom.xml` selects the script
through the `vsce.package.script` property, which is how a tagged release drives
it. See [../RELEASING.md](../RELEASING.md).

For a server plus extension build, first build OSATE, then run these from the
repository root in this order:

Expand Down
Loading
Loading