Skip to content

Commit

Permalink
Enable nightly pre-release builds
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Dec 23, 2022
1 parent 2c6b2f6 commit bf15b16
Show file tree
Hide file tree
Showing 9 changed files with 253 additions and 27 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,5 @@ jobs:
- uses: wntrblm/nox@2022.11.21
with:
python-versions: '3.7, 3.8, 3.9, 3.10'
- run: nox --session lint
- run: nox --session typecheck
- run: nox --session check
- run: nox --session test
66 changes: 58 additions & 8 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,39 @@ on:
create:
tags:
- v*
pull_request:
branches: [main]

env:
FETCH_DEPTH: 0 # pull in the tags for the version string
FETCH_DEPTH: 0

jobs:
dist:
build-id:
name: "Build ID"
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: ${{ env.FETCH_DEPTH }}
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Generate Build ID (release)
if: "startsWith(github.ref, 'refs/tags/')"
id: release-build-id-generator
run: |
export BUILD_ID=$(python -m build.generate_build_id --release)
echo "BUILD_ID=$BUILD_ID" >> $GITHUB_OUTPUT
- name: Generate Build ID (nightly)
if: "!startsWith(github.ref, 'refs/tags/')"
id: nightly-build-id-generator
run: |
export BUILD_ID=$(python -m build.generate_build_id)
echo "BUILD_ID=$BUILD_ID" >> $GITHUB_OUTPUT
- run: 'echo "BUILD_ID: $BUILD_ID"'

build:
strategy:
matrix:
include:
Expand All @@ -35,7 +62,8 @@ jobs:
target: aarch64-apple-darwin
code-target: darwin-arm64

name: dist (${{ matrix.target }})
name: Build (${{ matrix.target }})
needs: ['build-id']
runs-on: ${{ matrix.os }}
container: ${{ matrix.container }}

Expand All @@ -60,20 +88,35 @@ jobs:
# Install Node dependencies.
- run: npm ci

# Set the Build ID.
- name: Set Build ID (release)
if: "startsWith(github.ref, 'refs/tags/')"
run: |
python -m build.update_ext_version --build-id ${{ steps.release-build-id-generator.outputs.BUILD_ID }} --for-publishing --release
- name: Set Build ID (nightly)
if: "!startsWith(github.ref, 'refs/tags/')"
run: |
python -m build.update_ext_version --build-id ${{ steps.nightly-build-id-generator.outputs.BUILD_ID }} --for-publishing
# Build the extension.
- name: Package Extension
- name: Package Extension (release)
if: "startsWith(github.ref, 'refs/tags/')"
run: npx vsce package -o "./dist/ruff-${{ matrix.code-target }}.vsix" --target ${{ matrix.code-target }}
- name: Package Extension (nightly)
if: "!startsWith(github.ref, 'refs/tags/')"
run: npx vsce package -o "./dist/ruff-${{ matrix.code-target }}.vsix" --target ${{ matrix.code-target }} --pre-release

# Upload the extension.
- name: Upload artifacts
uses: actions/upload-artifact@v1
with:
name: dist-${{ matrix.target }}
path: ./dist

publish:
name: publish
name: "Publish"
needs: ['build']
runs-on: ubuntu-latest
needs: ['dist']
steps:
- name: Install Nodejs
uses: actions/setup-node@v3
Expand Down Expand Up @@ -120,12 +163,19 @@ jobs:
- run: npm ci

# Publish to the Code Marketplace.
- name: Publish Extension (Code Marketplace)
- name: Publish Extension (Code Marketplace, release)
if: "startsWith(github.ref, 'refs/tags/')"
run: npx vsce publish --pat ${{ secrets.MARKETPLACE_TOKEN }} --packagePath ./dist/ruff-*.vsix
- name: Publish Extension (Code Marketplace, nightly)
if: "!startsWith(github.ref, 'refs/tags/')"
run: npx vsce publish --pat ${{ secrets.MARKETPLACE_TOKEN }} --packagePath ./dist/ruff-*.vsix --pre-release

# Publish to OpenVSX.
- name: Publish Extension (OpenVSX)
- name: Publish Extension (OpenVSX, release)
if: "startsWith(github.ref, 'refs/tags/')"
run: npx ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ./dist/ruff-*.vsix
timeout-minutes: 2
- name: Publish Extension (OpenVSX, nightly)
if: "!startsWith(github.ref, 'refs/tags/')"
run: npx ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ./dist/ruff-*.vsix --pre-release
timeout-minutes: 2
24 changes: 24 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,27 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

---

MIT License

# TODO: Copyright (c) Microsoft Corporation.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,7 @@ This extension is based on the [Template for VS Code Python tools extensions](ht
### Development

- `nox --session fmt`
- `nox --session lint`
- `nox --session typecheck`
- `nox --session check`
- `nox --session test`

### Packaging and Publishing
Expand Down
70 changes: 70 additions & 0 deletions build/generate_build_id.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""Generate a build ID for a release or pre-release version."""

import argparse
import datetime
import json
import pathlib
from typing import Tuple, Union

EXT_ROOT = pathlib.Path(__file__).parent.parent
PACKAGE_JSON_PATH = EXT_ROOT / "package.json"


def is_even(v: Union[int, str]) -> bool:
"""Returns `True` if `v` is even."""
return not int(v) % 2


def micro_build_number() -> str:
"""Generates the micro build number.
The format is `1<Julian day><hour><minute>`.
"""
return f"1{datetime.datetime.now(tz=datetime.timezone.utc).strftime('%j%H%M')}"


def parse_version(version: str) -> Tuple[str, str, str, str]:
"""Parse a version string into a tuple of version parts."""
major, minor, parts = version.split(".", maxsplit=2)
try:
micro, suffix = parts.split("-", maxsplit=1)
except ValueError:
micro = parts
suffix = ""
return major, minor, micro, suffix


def main(package_json: pathlib.Path, *, release: bool) -> None:
package = json.loads(package_json.read_text(encoding="utf-8"))

major, minor, micro, suffix = parse_version(package["version"])

if release and not is_even(minor):
raise ValueError(
f"Release version should have EVEN numbered minor version: "
f"{package['version']}"
)
elif not release and is_even(minor):
raise ValueError(
f"Pre-Release version should have ODD numbered minor version: "
f"{package['version']}"
)

if release:
print(micro)
else:
print(micro_build_number())


if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Generate a build ID for a release or pre-release version."
)
parser.add_argument(
"--release",
action="store_true",
help="Treats the current build as a release build.",
)
args = parser.parse_args()

main(PACKAGE_JSON_PATH, release=args.release)
90 changes: 90 additions & 0 deletions build/update_ext_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
"""Update the Python extension micro version based on a build ID."""

import argparse
import json
import pathlib
from typing import Tuple, Union

EXT_ROOT = pathlib.Path(__file__).parent.parent
PACKAGE_JSON_PATH = EXT_ROOT / "package.json"


def is_even(v: Union[int, str]) -> bool:
"""Returns True if `v` is even."""
return not int(v) % 2


def parse_version(version: str) -> Tuple[str, str, str, str]:
"""Parse a version string into a tuple of version parts."""
major, minor, parts = version.split(".", maxsplit=2)
try:
micro, suffix = parts.split("-", maxsplit=1)
except ValueError:
micro = parts
suffix = ""
return major, minor, micro, suffix


def main(
package_json: pathlib.Path, *, release: bool, build_id: int, for_publishing: bool
) -> None:
package = json.loads(package_json.read_text(encoding="utf-8"))

major, minor, micro, suffix = parse_version(package["version"])

if release and not is_even(minor):
raise ValueError(
f"Release version should have EVEN numbered minor version: "
f"{package['version']}"
)
elif not release and is_even(minor):
raise ValueError(
f"Pre-Release version should have ODD numbered minor version: "
f"{package['version']}"
)

# The build ID should fall within the 0-INT32 max range allowed by the Marketplace.
if build_id < 0 or (for_publishing and build_id > ((2**32) - 1)):
raise ValueError(f"Build ID must be within [0, {(2**32) - 1}]")

print(f"Updating build FROM: {package['version']}")
package["version"] = ".".join((major, minor, str(build_id)))
if not for_publishing and not release and len(suffix):
package["version"] += "-" + suffix
print(f"Updating build TO: {package['version']}")

# Overwrite package.json with new data.
package_json.write_text(
json.dumps(package, indent=4, ensure_ascii=False) + "\n", encoding="utf-8"
)


if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Update the Python extension micro version based on a build ID."
)
parser.add_argument(
"--release",
action="store_true",
help="Treats the current build as a release build.",
)
parser.add_argument(
"--build-id",
action="store",
type=int,
help="Micro version to use.",
required=True,
)
parser.add_argument(
"--for-publishing",
action="store_true",
help="Removes `-dev` or `-rc` suffix.",
)
args = parser.parse_args()

main(
PACKAGE_JSON_PATH,
release=args.release,
build_id=args.build_id,
for_publishing=args.for_publishing,
)
18 changes: 6 additions & 12 deletions noxfile.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import json
import pathlib
import urllib.request as url_lib
Expand Down Expand Up @@ -125,31 +122,26 @@ def test(session: nox.Session) -> None:


@nox.session(python="3.10")
def lint(session: nox.Session) -> None:
def check(session: nox.Session) -> None:
"""Lint the Python and TypeScript source files."""
session.install("-r", "./requirements.txt")
session.install("-r", "./requirements-dev.txt")

# Check Python lint with Ruff.
session.run("ruff", "./noxfile.py")
session.run("ruff", "./bundled/tool")
session.run("ruff", "./build")
session.run("ruff", "./src/test/python_tests")

# Check Python formatting with Black.
session.run("black", "--check", "./noxfile.py")
session.run("black", "--check", "./bundled/tool")
session.run("black", "--check", "./build")
session.run("black", "--check", "./src/test/python_tests")

# Check TypeScript code.
session.run("npm", "run", "lint", external=True)


@nox.session(python="3.10")
def typecheck(session: nox.Session) -> None:
"""Typecheck the Python and TypeScript source files."""
session.install("-r", "./requirements.txt")
session.install("-r", "./requirements-dev.txt")

# Check Python types with Mypy.
session.run("mypy")

Expand All @@ -166,11 +158,13 @@ def fmt(session: nox.Session) -> None:
# Sort imports with Ruff.
session.run("ruff", "--select", "I001", "--fix", "./noxfile.py")
session.run("ruff", "--select", "I001", "--fix", "./bundled/tool")
session.run("ruff", "--select", "I001", "--fix", "./build")
session.run("ruff", "--select", "I001", "--fix", "./src/test/python_tests")

# Format Python with Black.
session.run("black", "./noxfile.py")
session.run("black", "./bundled/tool")
session.run("black", "./build")
session.run("black", "./src/test/python_tests")

# Format TypeScript with Prettier.
Expand All @@ -193,4 +187,4 @@ def update_packages(session: nox.Session) -> None:
_update_npm_packages(session)


nox.options.sessions = ["test", "lint", "typecheck"]
nox.options.sessions = ["test", "check"]
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "ruff",
"displayName": "Ruff",
"description": "A Visual Studio Code extension with support for the Ruff linter.",
"version": "2022.0.26",
"version": "2022.1.0-dev",
"serverInfo": {
"name": "Ruff",
"module": "ruff"
Expand Down
Loading

0 comments on commit bf15b16

Please sign in to comment.