diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..f54fbcd --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,7 @@ +version: 2 +updates: + + - package-ecosystem: github-actions + directory: / + schedule: + interval: monthly diff --git a/.github/release.yaml b/.github/release.yaml new file mode 100644 index 0000000..0f4884c --- /dev/null +++ b/.github/release.yaml @@ -0,0 +1,18 @@ +changelog: + exclude: + labels: + - ignore-for-release + authors: + - dependabot + categories: + - title: Breaking Changes 🛠 + labels: + - semver-major + - breaking-change + - title: New Features 🎉 + labels: + - semver-minor + - enhancement + - title: Other Changes + labels: + - '*' diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..c51b39e --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,42 @@ +name: Build +on: [push] +jobs: + build: + strategy: + matrix: + os: [macos-11, ubuntu-22.04, windows-2022] + addrsize: ["64"] + archive-format: ["tzst"] + python-architecture: ["x64"] +## As of 2023-05-17, the autobuild package produced by either "tbz2" or "tgz" +## is unreadable by the Python 3.10 or 3.11 tarfile module. But as the "tzst" +## issue remains with 32-bit Python, use 64-bit Python for all platforms. +## include: +## - os: windows-2022 +## addrsize: "32" +## # workaround for zstandard/pyzstd memory issues on 32-bit +## # pyzstd.ZstdError: Unable to compress zstd data: Allocation error : not enough memory +## archive-format: "tbz2" +## python-architecture: "x86" + continue-on-error: false + runs-on: ${{ matrix.os }} + steps: + - uses: actions/setup-python@v4 + with: + python-version: "3.x" + architecture: ${{ matrix.python-architecture }} + - name: Install Python packages + run: pip3 install -U eventlet llbase pytest PyInstaller requests + - uses: secondlife/action-autobuild@v3 + with: + addrsize: ${{ matrix.addrsize }} + archive-format: ${{ matrix.archive-format }} + setup-python: false + release: + needs: build + runs-on: [ubuntu-latest] + if: startsWith(github.ref, 'refs/tags/v') + steps: + - uses: secondlife/action-autobuild-release@v2 + with: + public: true diff --git a/README.md b/README.md index c6f6f5d..0761db1 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,8 @@ Viewer Management Process ========================= -This is the master process that is launched for the Second Life -Viewer (https://bitbucket.org/lindenlab/viewer-release). It manages -updates and will soon manage crash data collection and reporting. +This is the updater process that is launched for the Second Life +Viewer (https://github.com/secondlife/viewer). -To build it, you'll need to have the python 'nose' package installed. -You need the 'nose' package (a python testing framework) installed: - -`pip install nose` - -and set the `nosetests` environment to the location of the `nosetests` -executable. If you installed nose such that it is in your path, this -will work: - -``` -export nosetests=nosetests; -autobuild build -autobuild package -``` - -If you want to support both 32 and 64 bit Windows, you'll need to -build this with a 32 bit Windows python and use the resulting .exe for -both. +If you want to support both 32 and 64 bit Windows, you'll need to build this +with a 32 bit Python interpreter and use the resulting .exe for both. diff --git a/build-cmd.py b/build-cmd.py index f5b8e86..cd8367d 100644 --- a/build-cmd.py +++ b/build-cmd.py @@ -27,7 +27,6 @@ # Check https://wiki.lindenlab.com/wiki/How_To_Start_Using_Autobuild/Examples for info on how to build this package from shutil import copy, rmtree -import cgitb from collections import deque from contextlib import suppress import errno @@ -46,19 +45,12 @@ import trace # set this up early to report crashes in anything that follows -cgitb.enable(format='text') - -# Python packages on which our build depends. Each entry maps a package name -# (the name you would 'import') to the string you would use to 'pip install' -# that package. That may include any version qualifiers, or whatever, -# recognized by pip. -BUILD_DEPS = dict( - eventlet='eventlet', - llbase='llbase', - pytest='pytest', - PyInstaller='pyinstaller', - requests='requests', -) +try: + import cgitb + cgitb.enable(format='text') +except ImportError: + # sigh, they should not have deprecated and removed this + pass class Error(Exception): pass @@ -88,29 +80,6 @@ def main(): stage_VMP = os.path.join(stage, "VMP") build = os.path.join(top, 'build') - # ensure we're running in a virtualenv - try: - virtualenv = os.environ["VIRTUAL_ENV"] - except KeyError as err: - raise Error('Run %s within a virtualenv: it uses pip install' % scriptname) from err - - # Install the Python packages on which this build depends. - # iterating over a dict produces just its keys - print("Installing %s into virtualenv: %s" % - (', '.join(BUILD_DEPS), virtualenv)) - - try: - # 'python -m pip' is recommended since, if you just invoke 'pip', you - # could end up finding a different pip than the one associated with - # the Python interpreter running the current script. - # https://pip.pypa.io/en/latest/user_guide/#using-pip-from-your-program - # -U means: even if we already have an older version of (say) requests - # in the system image, ensure our virtualenv has the version specified - # in RUNTIME_DEPS (or the latest version if not version-locked). - run(sys.executable, '-m', 'pip', 'install', '-U', *BUILD_DEPS.values()) - except RunError as err: - raise Error(str(err)) from err - # Make sure our staging area is clean because our manifest sweeps up # whatever's in this directory. with suppress(FileNotFoundError): @@ -137,15 +106,8 @@ def main(): test_env.pop('LIB', None) test_env.pop('WINDOWSSDK_EXECUTABLEPATH_X64', None) - # If we were to run pytest installed in system Python, as opposed to - # our virtualenv, then the scripts under test won't be able to import - # (e.g.) eventlet -- which is only in our virtualenv, not system Python. - # The tricky thing is that if system Python already contains an up-to-date - # version of pytest, 'pip install -U pytest' won't actually write anything to - # our virtualenv. - # So instead, invoke pytest using the alternate tactic in which we - # explicitly run python, the one from our virtualenv, explicitly invoking - # the pytest module: + # Invoke pytest using the alternate tactic in which we explicitly run + # python, our own interpreter, explicitly invoking the pytest module: # https://docs.pytest.org/en/latest/how-to/usage.html#calling-pytest-through-python-m-pytest command = [sys.executable, '-m', 'pytest', tests] print("About to call %s\n" @@ -241,19 +203,11 @@ def pyinstaller(mainfile, dstdir, icon, manifest_from_build=None): manifest = os.path.join(manifest_from_build, basebase, basebase + '.exe.manifest') # https://msdn.microsoft.com/en-us/library/ms235591.aspx try: - run('mt.exe', '-manifest', manifest, '-outputresource:%s;1' % exe) - except RunError as e: + subprocess.check_call( + ['mt.exe', '-manifest', manifest, '-outputresource:%s;1' % exe]) + except subprocess.CalledProcessError as e: raise Error("Couldn't embed manifest %s in %s: %s" % (manifest, exe, e)) from e -# We don't bother to catch CalledProcessError and reraise it as RunError; we -# just alias the original exception. -RunError = subprocess.CalledProcessError - -def run(*command, **kwds): - print_command(*command) - # it's caller's responsibility to catch RunError - return subprocess.check_call(command, **kwds) - def print_command(*command): print(' '.join(shlex.quote(word) for word in command), flush=True)