From 89493ab1f8354c87964a0c9373e17a74261651b1 Mon Sep 17 00:00:00 2001 From: Ryan Volz Date: Mon, 10 Apr 2023 16:28:51 -0400 Subject: [PATCH 1/4] Replace curses with asciimatics for Windows compatibility. --- python/adsb/decoder.py | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/python/adsb/decoder.py b/python/adsb/decoder.py index 6bca309..f369754 100644 --- a/python/adsb/decoder.py +++ b/python/adsb/decoder.py @@ -19,8 +19,8 @@ # Boston, MA 02110-1301, USA. # +import asciimatics.screen import atexit -import curses import datetime import logging import os @@ -288,11 +288,9 @@ def __init__(self, msg_filter, error_corr, print_level): if self.print_level == "Brief": logging.basicConfig(format='[%(levelname)s] %(message)s', level=logging.CRITICAL) - atexit.register(curses.endwin) - self.screen = curses.initscr() - self.screen.addstr(0, 0, "{:^8s} {:^6s} {:^8s} {:^5s} {:^5s} {:^5s} {:^5s} {:^11s} {:^11s} {:^4s}".format("Time", "ICAO", "Callsign", "Alt", "Climb", "Speed", "Hdng", "Latitude", "Longitude", "Msgs"), curses.A_BOLD) - self.screen.addstr(1, 0, "{:^8s} {:>6s} {:>8s} {:>5s} {:>5s} {:>5s} {:>5s} {:>11s} {:>11s} {:>4s}".format("", "", "", "ft", "ft/m", "kt", "deg", "deg", "deg", ""), curses.A_DIM) - self.screen.refresh() + self.screen = asciimatics.screen.Screen.open() + atexit.register(self.screen.close) + self.screen.clear() else: logging.basicConfig(format='[%(levelname)s] %(message)s', level=logging.DEBUG) @@ -450,8 +448,21 @@ def reset_plane_altimetry(self, plane): def print_planes(self): + self.screen.reset() + self.screen.clear_buffer( + self.screen.COLOUR_WHITE, + self.screen.A_NORMAL, + self.screen.COLOUR_BLACK, + 0, + 0, + self.screen.dimensions[1], + self.screen.dimensions[0], + ) + self.screen.print_at("{:^8s} {:^6s} {:^8s} {:^5s} {:^5s} {:^5s} {:^5s} {:^11s} {:^11s} {:^4s}".format("Time", "ICAO", "Callsign", "Alt", "Climb", "Speed", "Hdng", "Latitude", "Longitude", "Msgs"), 0, 0, colour=self.screen.COLOUR_BLUE, attr=self.screen.A_BOLD) + self.screen.print_at("{:^8s} {:>6s} {:>8s} {:>5s} {:>5s} {:>5s} {:>5s} {:>11s} {:>11s} {:>4s}".format("", "", "", "ft", "ft/m", "kt", "deg", "deg", "deg", ""), 0, 1, colour=self.screen.COLOUR_CYAN, attr=self.screen.A_NORMAL) + index = 0 - for icao in self.plane_dict: + for index, icao in enumerate(self.plane_dict): last_seen = datetime.datetime.utcfromtimestamp(self.timestamp).strftime("%H:%M:%S") if self.plane_dict[icao]["callsign"] is not None: @@ -492,7 +503,7 @@ def print_planes(self): num_msgs = "{:4d}".format(self.plane_dict[icao]["num_msgs"]) age = "{:3.0f}".format(int(time.time()) - self.plane_dict[icao]["last_seen"]) - self.screen.addstr(2 + index, 0, "{:8s} {:6s} {} {} {} {} {} {} {} {}".format( + self.screen.print_at("{:8s} {:6s} {} {} {} {} {} {} {} {}".format( last_seen, icao, callsign, @@ -503,11 +514,10 @@ def print_planes(self): latitude, longitude, num_msgs - )) - self.screen.refresh() - - index += 1 + ), 0, 2 + index, attr=self.screen.A_NORMAL) + self.screen.move(0, 3 + index) + self.screen.refresh() def publish_decoded_pdu(self, aa_str): decoded = self.plane_dict[aa_str].copy() @@ -759,7 +769,7 @@ def correct_burst_errors(self): self.log("debug", "FEC", "Conservative error correction lookup failed to get syndrome") else: self.log("debug", "FEC", "Conservative error correction lookup failed to get syndromes for length " + str(self.payload_length)) - + return 0 def correct_errors(self): From ea92ec94001f9c3f385035fcf1c2df3be2518119 Mon Sep 17 00:00:00 2001 From: Ryan Volz Date: Tue, 11 Apr 2023 15:21:07 -0400 Subject: [PATCH 2/4] Make webserver compatible with latest flask-socketio & company. --- web/static/index.html | 2 +- web/webserver.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web/static/index.html b/web/static/index.html index 2089b4b..9667715 100644 --- a/web/static/index.html +++ b/web/static/index.html @@ -37,7 +37,7 @@
- + diff --git a/web/webserver.py b/web/webserver.py index d1aeefb..97c81df 100755 --- a/web/webserver.py +++ b/web/webserver.py @@ -38,7 +38,7 @@ app = Flask(__name__, static_url_path="") app.config["SECRET_KEY"] = "secret!" -socketio = SocketIO(app) +socketio = SocketIO(app, cors_allowed_origins=f"http://{HTTP_ADDRESS}:{HTTP_PORT}") def zmq_thread(): From fce58e512e2b3d088001d038a33da6159ed96c88 Mon Sep 17 00:00:00 2001 From: Ryan Volz Date: Mon, 10 Apr 2023 16:31:48 -0400 Subject: [PATCH 3/4] Add conda recipe. --- .conda/README.md | 110 ++++++++++++++++++++++++++ .conda/conda-forge.yml | 33 ++++++++ .conda/recipe/bld.bat | 32 ++++++++ .conda/recipe/build.sh | 24 ++++++ .conda/recipe/conda_build_config.yaml | 14 ++++ .conda/recipe/meta.yaml | 90 +++++++++++++++++++++ 6 files changed, 303 insertions(+) create mode 100644 .conda/README.md create mode 100644 .conda/conda-forge.yml create mode 100644 .conda/recipe/bld.bat create mode 100644 .conda/recipe/build.sh create mode 100644 .conda/recipe/conda_build_config.yaml create mode 100644 .conda/recipe/meta.yaml diff --git a/.conda/README.md b/.conda/README.md new file mode 100644 index 0000000..5b70681 --- /dev/null +++ b/.conda/README.md @@ -0,0 +1,110 @@ +# gr-adsb conda recipe + +This recipe is for creating a package that can be installed into a [conda](https://docs.conda.io/en/latest/) environment. See the [Conda GNU Radio Guide](https://wiki.gnuradio.org/index.php/CondaInstall) for more information on using GNU Radio with conda. + +Packages for GNU Radio and some out-of-tree (OOT) modules are available through the [`conda-forge` channel](https://conda-forge.org/). If this OOT module is already available (search "gnuradio" on [anaconda.org](https://anaconda.org)), it is preferable to use that existing package rather than this recipe. + +#### Users + +- [Building the package](#building-the-package) + +#### Developers + +- [Modifying the recipe](#modifying-the-recipe) +- [Continuous integration](#continuous-integration) + + +## Building the package + +(See the [Conda GNU Radio Guide](https://wiki.gnuradio.org/index.php/CondaInstall) if you are unfamiliar with how to use conda.) + +1. Make sure that have `conda-build` and `conda-forge-pinning` installed and updated in your base environment: + + conda activate base + conda install -n base conda-build conda-forge-pinning + conda upgrade -n base conda-build conda-forge-pinning + + **Windows users only**: you will also need to have Microsoft's Visual C++ build tools installed. Usually you can do this by installing the [Community edition of Visual Studio](https://visualstudio.microsoft.com/free-developer-offers/) and then selecting a MSVC C++ x64/x86 build tools component under the list of "Individual Components". As of this writing, you will specifically need MSVC v141, i.e. the "MSVC v141 - VS2017 C++ x64/x86 build tools (v14.16)" component. If the build fails to find the version of MSVC it is looking for, try installing other (newer) versions. + +2. Download the source code for this OOT module (which includes this recipe). Typically, this is done by using `git` and cloning the module's repository: + + git clone + cd + +3. Run `conda-build` on the recipe to create the package: + + (Linux and macOS) + + conda build .conda/recipe/ -m ${CONDA_PREFIX}/conda_build_config.yaml + + (Windows) + + conda build .conda\recipe\ -m %CONDA_PREFIX%\conda_build_config.yaml + + If you plan on using this package within an existing environment which uses a specific version of Python, specify the version of Python using the `--python` flag. You must use a version string that matches one of the strings listed under `python` in the `${CONDA_PREFIX}/conda_build_config.yaml` file, e.g: + + (Linux and macOS) + + conda build .conda/recipe/ -m ${CONDA_PREFIX}/conda_build_config.yaml --python="3.9.* *_cpython" + + (Windows) + + conda build .conda\recipe\ -m %CONDA_PREFIX%\conda_build_config.yaml --python="3.9.* *_cpython" + + If you encounter errors, consult with the OOT module maintainer or the maintainers of the [gnuradio feedstock](https://github.com/conda-forge/gnuradio-feedstock). It is possible that the recipe will need to be updated. + +4. Install the package into an existing environment + + conda install --use-local -n gnuradio-EXAMPLE + + or create a new environment that includes the package: + + conda create -n test_env gnuradio-EXAMPLE + + +## Modifying the recipe + +This recipe is derived from a template, and so it is best to check it and make any necessary modifications. Likely changes include: + +- Populating metadata near the bottom of the `recipe/meta.yaml` file +- Adding "host" (build-time) and "run" (run-time) dependencies specific to your module in `recipe/meta.yaml` +- Adding special configuration flags or steps are necessary to carry out the build to the build scripts (`recipe/build.sh` for Linux/macOS and `recipe/bld.bat` for Windows) + +Specifying the versions of GNU Radio that your OOT is compatible with is one of the most important modifications. Following the instructions below, the module will be built against the conda-forge "pinned" version of GNU Radio, which is usually the latest version. + +- To override the pinned version of GNU Radio (e.g. for a branch that builds against an older version), specify the `gnuradio_core` key as instructed in `recipe/conda_build_config.yaml`. +- If the module is compatible with multiple major versions of GNU Radio, and you want to build against multiple of them, you can also add extra versions to `recipe/conda_build_config.yaml` to expand the default build matrix. + +See the [conda-build documentation](https://docs.conda.io/projects/conda-build/en/latest/index.html) for details on how to write a conda recipe. + + +## Continuous integration + +Only a few steps are needed to use this recipe to build and test this OOT module using CI services. It can also be used to upload packages to [anaconda.org](https://anaconda.org) for others to download and use. + +1. Make sure that have `conda-smithy` installed in your base conda environment: + + conda activate base + conda install -n base conda-smithy + conda upgrade -n base conda-smithy + +2. Make any changes to the recipe and `conda-forge.yml` that are necessary. For example, if you plan on uploading packages to your own [anaconda.org](https://anaconda.org) channel, specify the channel name and label as the `channel_targets` key in `recipe/conda_build_config.yaml`. Commit the changes to your repository: + + git commit -a + +3. "Re-render" the CI scripts by running conda-smithy from the root of your repository: + + conda-smithy rerender --feedstock_config .conda/conda-forge.yml -c auto + + This will create a commit that adds or updates the CI scripts that have been configured with `conda-forge.yml`. If you want to minimize extraneous files, you can remove some of the newly-created files that are not necessary outside of a typical conda-forge feedstock: + + git rm -f .github/workflows/automerge.yml .github/workflows/webservices.yml .circleci/config.yml + git commit --amend -s + + When the CI is executed (on a pull request or commit), it will run one job per configuration file in `.ci_support` to build packages for various platforms, Python versions, and optionally `gnuradio` versions (by adding to `gnuradio_extra_pin` in `recipe/conda_build_config.yaml`). + + **You should repeat this step whenever the recipe is updated or when changes to the conda-forge infrastructure require all CI scripts to be updated.** + + Since the newly created files will be rewritten whenever conda-smithy is run, you should not edit any of the automatically-generated files in e.g. `.ci_support`, `.scripts`, or `.github/workflows/conda-build.yml`. + +4. (optional) If you want to enable uploads of the packages to [anaconda.org](https://anaconda.org) whenever the CI is run from a commit on the branch specified in `conda-forge.yml`, you need to set an Anaconda Cloud API token to the `BINSTAR_TOKEN` environment variable. To generate a token, follow the instructions [here](https://docs.anaconda.com/anacondaorg/user-guide/tasks/work-with-accounts/#creating-access-tokens). To populate the `BINSTAR_TOKEN` environment variable for CI jobs, add the token as a secret by following, for example, the [Github docs](https://docs.github.com/en/actions/reference/encrypted-secrets). diff --git a/.conda/conda-forge.yml b/.conda/conda-forge.yml new file mode 100644 index 0000000..1cdd5bc --- /dev/null +++ b/.conda/conda-forge.yml @@ -0,0 +1,33 @@ +# See https://conda-forge.org/docs/maintainer/conda_forge_yml.html for +# documentation on possible keys and values. + +# uncomment to enable cross-compiled osx-arm64 builds +#build_platform: +# osx_arm64: osx_64 +clone_depth: 0 +github_actions: + store_build_artifacts: true +noarch_platforms: + - linux_64 + - win_64 +os_version: + linux_64: cos7 +provider: + linux: github_actions + osx: github_actions + win: github_actions + # uncomment to enable additional linux platforms + #linux_aarch64: github_actions + #linux_ppc64le: github_actions +recipe_dir: .conda/recipe +# skip unnecessary files since this is not a full-fledged conda-forge feedstock +skip_render: + - README.md + - LICENSE.txt + - .gitattributes + - .gitignore + - build-locally.py + - LICENSE +test: native_and_emulated +# enable uploads to Anaconda Cloud from specified branches only +upload_on_branch: main diff --git a/.conda/recipe/bld.bat b/.conda/recipe/bld.bat new file mode 100644 index 0000000..2d139ad --- /dev/null +++ b/.conda/recipe/bld.bat @@ -0,0 +1,32 @@ +setlocal EnableDelayedExpansion +@echo on + +:: Make a build folder and change to it +cmake -E make_directory buildconda +cd buildconda + +:: configure +cmake -G "Ninja" ^ + -DCMAKE_BUILD_TYPE:STRING=Release ^ + -DCMAKE_INSTALL_PREFIX:PATH="%LIBRARY_PREFIX%" ^ + -DCMAKE_PREFIX_PATH:PATH="%LIBRARY_PREFIX%" ^ + -DGR_PYTHON_DIR:PATH="%SP_DIR%" ^ + -DENABLE_DOXYGEN=OFF ^ + -DENABLE_TESTING=ON ^ + .. +if errorlevel 1 exit 1 + +:: build +cmake --build . --config Release -- -j%CPU_COUNT% +if errorlevel 1 exit 1 + +:: install +cmake --build . --config Release --target install +if errorlevel 1 exit 1 + +cmake -E copy_directory ..\web %SP_DIR%\gnuradio\adsb +if errorlevel 1 exit 1 + +:: test +ctest --build-config Release --output-on-failure --timeout 120 -j%CPU_COUNT% +if errorlevel 1 exit 1 diff --git a/.conda/recipe/build.sh b/.conda/recipe/build.sh new file mode 100644 index 0000000..1be8064 --- /dev/null +++ b/.conda/recipe/build.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +set -ex + +cmake -E make_directory buildconda +cd buildconda + +cmake_config_args=( + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_PREFIX=$PREFIX + -DLIB_SUFFIX="" + -DENABLE_DOXYGEN=OFF + -DENABLE_TESTING=ON +) + +cmake ${CMAKE_ARGS} -G "Ninja" .. "${cmake_config_args[@]}" +cmake --build . --config Release -- -j${CPU_COUNT} +cmake --build . --config Release --target install + +cmake -E copy_directory ../web $SP_DIR/gnuradio/adsb + +if [[ "${CONDA_BUILD_CROSS_COMPILATION:-}" != "1" || "${CROSSCOMPILING_EMULATOR}" != "" ]]; then + ctest --build-config Release --output-on-failure --timeout 120 -j${CPU_COUNT} +fi diff --git a/.conda/recipe/conda_build_config.yaml b/.conda/recipe/conda_build_config.yaml new file mode 100644 index 0000000..ce9c0f6 --- /dev/null +++ b/.conda/recipe/conda_build_config.yaml @@ -0,0 +1,14 @@ +# this is the channel and label where packages will be uploaded to if enabled +# (see ../README.md) +channel_targets: + - gnuradio main +# override the conda-forge pin for gnuradio-core by uncommenting +# and specifying a different version here +#gnuradio_core: + #- "3.10.1" +gnuradio_extra_pin: + # always leave one entry with the empty string + - "" + # add version strings here like to get builds for versions other than + # the conda-forge-wide default or version specified above for gnuradio_core + #- "3.9.5" diff --git a/.conda/recipe/meta.yaml b/.conda/recipe/meta.yaml new file mode 100644 index 0000000..22842e5 --- /dev/null +++ b/.conda/recipe/meta.yaml @@ -0,0 +1,90 @@ +{% set oot_name = "adsb" %} +{% set name = "gnuradio-" + oot_name %} +# Set package version from cleaned up git tags if possible, +# otherwise fall back to date-based version. +{% set tag_version = environ.get("GIT_DESCRIBE_TAG", "")|string|replace("-","_")|replace("v","")|replace("git","") %} +{% set post_commit = environ.get("GIT_DESCRIBE_NUMBER", 0)|string %} +{% set hash = environ.get("GIT_DESCRIBE_HASH", "local")|string %} +{% set fallback_version = "0.0.0.{0}.dev+g{1}".format(datetime.datetime.now().strftime("%Y%m%d"), environ.get("GIT_FULL_HASH", "local")[:9]) %} +{% set version = (tag_version if post_commit == "0" else "{0}.post{1}+{2}".format(tag_version, post_commit, hash)) if tag_version else fallback_version %} + +package: + name: {{ name|lower }} + version: {{ version }} + +source: + # use local path or git repository depending on if the build is local or done on CI + path: "../.." # [not os.environ.get("CI")] + git_url: {{ environ.get('FEEDSTOCK_ROOT', "../..") }} # [os.environ.get("CI")] + +build: + number: 0 + noarch: python + string: "unix_pyh{{ PKG_HASH }}_{{ PKG_BUILDNUM }}" # [unix] + string: "win_pyh{{ PKG_HASH }}_{{ PKG_BUILDNUM }}" # [win] + ignore_run_exports_from: + - {{ compiler('c') }} + - {{ compiler('cxx') }} + +requirements: + build: + - {{ compiler("c") }} + - {{ compiler("cxx") }} + - cmake + - git + - ninja + - pkg-config + + host: + - asciimatics + - colorama + # the following two entries are for generating builds against specific GR versions + - gnuradio-core # [not gnuradio_extra_pin] + - gnuradio-core {{ gnuradio_extra_pin }}.* # [gnuradio_extra_pin] + - libboost-headers + - numpy + - pip # [win] + - python >=3.8 + + run: + - __unix # [unix] + - __win # [win] + - asciimatics + - colorama + - flask + - flask-socketio >=5,<6 + - gevent + - gevent-websocket + # Need gnuradio as a run dep because noarch doesn't do run_exports. + # This pin can be more relaxed than the gnuradio run_exports because the + # API is stable at the 'x.x' level and we don't need to worry about ABI. + - {{ pin_compatible('gnuradio-core', min_pin='x.x', max_pin='x.x') }} + - numpy + - python >=3.8 + - pyzmq + +test: + commands: + # verify that (some) GRC blocks get installed + {% set blocks = ["framer", "demod", "decoder"] %} + {% for block in blocks %} + - test -f $PREFIX/share/gnuradio/grc/blocks/{{ oot_name }}_{{ block }}.block.yml # [not win] + - if not exist %PREFIX%\\Library\\share\\gnuradio\\grc\\blocks\\{{ oot_name }}_{{ block }}.block.yml exit 1 # [win] + {% endfor %} + + imports: + # verify that the python module imports + - gnuradio.{{ oot_name }} + - gnuradio.{{ oot_name }}.webserver + +about: + home: https://github.com/mhostetter/gr-adsb + license: GPL-3.0-or-later + license_file: COPYING + summary: GNU Radio module to demodulate and decode ADS-B messages + description: > + A GNU Radio out-of-tree (OOT) module to demodulate and decode Automatic + Dependent Surveillance Broadcast (ADS-B) messages. + + To use the built-in web app, run `python -m gnuradio.adsb.webserver` and + open a browser to http://127.0.0.1:5000. From bc275bf7dde189fd611e0e3478b144f3808fc8b1 Mon Sep 17 00:00:00 2001 From: Ryan Volz Date: Tue, 31 Oct 2023 10:29:31 -0400 Subject: [PATCH 4/4] MNT: Re-rendered with conda-build 3.24.0, conda-smithy 3.27.1, and conda-forge-pinning 2023.10.30.17.31.54 --- .ci_support/README | 6 + .ci_support/linux_64_.yaml | 25 ++++ .ci_support/win_64_.yaml | 14 +++ .circleci/config.yml | 25 ++++ .github/workflows/automerge.yml | 19 +++ .github/workflows/conda-build.yml | 143 +++++++++++++++++++++++ .github/workflows/webservices.yml | 13 +++ .scripts/build_steps.sh | 84 +++++++++++++ .scripts/create_conda_build_artifacts.sh | 113 ++++++++++++++++++ .scripts/logging_utils.sh | 35 ++++++ .scripts/run_docker_build.sh | 103 ++++++++++++++++ .scripts/run_win_build.bat | 113 ++++++++++++++++++ 12 files changed, 693 insertions(+) create mode 100644 .ci_support/README create mode 100644 .ci_support/linux_64_.yaml create mode 100644 .ci_support/win_64_.yaml create mode 100644 .circleci/config.yml create mode 100644 .github/workflows/automerge.yml create mode 100644 .github/workflows/conda-build.yml create mode 100644 .github/workflows/webservices.yml create mode 100755 .scripts/build_steps.sh create mode 100755 .scripts/create_conda_build_artifacts.sh create mode 100644 .scripts/logging_utils.sh create mode 100755 .scripts/run_docker_build.sh create mode 100755 .scripts/run_win_build.bat diff --git a/.ci_support/README b/.ci_support/README new file mode 100644 index 0000000..a47316b --- /dev/null +++ b/.ci_support/README @@ -0,0 +1,6 @@ +This file is automatically generated by conda-smithy. If any +particular build configuration is expected, but it is not found, +please make sure all dependencies are satisfiable. To add/modify any +matrix elements, you should create/change conda-smithy's input +recipe/conda_build_config.yaml and re-render the recipe, rather than +editing these files directly. diff --git a/.ci_support/linux_64_.yaml b/.ci_support/linux_64_.yaml new file mode 100644 index 0000000..094905d --- /dev/null +++ b/.ci_support/linux_64_.yaml @@ -0,0 +1,25 @@ +c_compiler: +- gcc +c_compiler_version: +- '12' +cdt_name: +- cos7 +channel_sources: +- conda-forge +channel_targets: +- gnuradio main +cxx_compiler: +- gxx +cxx_compiler_version: +- '12' +docker_image: +- quay.io/condaforge/linux-anvil-cos7-x86_64 +gnuradio_core: +- 3.10.8 +gnuradio_extra_pin: +- '' +numpy: +- '1.23' +zip_keys: +- - c_compiler_version + - cxx_compiler_version diff --git a/.ci_support/win_64_.yaml b/.ci_support/win_64_.yaml new file mode 100644 index 0000000..ea806d3 --- /dev/null +++ b/.ci_support/win_64_.yaml @@ -0,0 +1,14 @@ +c_compiler: +- vs2019 +channel_sources: +- conda-forge +channel_targets: +- gnuradio main +cxx_compiler: +- vs2019 +gnuradio_core: +- 3.10.8 +gnuradio_extra_pin: +- '' +numpy: +- '1.23' diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..8b4ef2f --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,25 @@ +# This file was generated automatically from conda-smithy. To update this configuration, +# update the conda-forge.yml and/or the recipe/meta.yaml. +# -*- mode: jinja-yaml -*- + +version: 2 + +jobs: + build: + working_directory: ~/test + machine: + image: ubuntu-2004:current + steps: + - run: + # The Circle-CI build should not be active, but if this is not true for some reason, do a fast finish. + command: exit 0 + +workflows: + version: 2 + build_and_test: + jobs: + - build: + filters: + branches: + ignore: + - /.*/ diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml new file mode 100644 index 0000000..da1368a --- /dev/null +++ b/.github/workflows/automerge.yml @@ -0,0 +1,19 @@ +on: + status: {} + check_suite: + types: + - completed + +jobs: + automerge-action: + runs-on: ubuntu-latest + name: automerge + steps: + - name: checkout + uses: actions/checkout@v3 + - name: automerge-action + id: automerge-action + uses: conda-forge/automerge-action@main + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + rerendering_github_token: ${{ secrets.RERENDERING_GITHUB_TOKEN }} diff --git a/.github/workflows/conda-build.yml b/.github/workflows/conda-build.yml new file mode 100644 index 0000000..215c113 --- /dev/null +++ b/.github/workflows/conda-build.yml @@ -0,0 +1,143 @@ +# This file was generated automatically from conda-smithy. To update this configuration, +# update the conda-forge.yml and/or the recipe/meta.yaml. +# -*- mode: yaml -*- + +name: Build conda package +on: [push, pull_request] + +jobs: + build: + name: ${{ matrix.CONFIG }} + runs-on: ${{ matrix.os }}-latest + strategy: + fail-fast: false + matrix: + include: + - CONFIG: linux_64_ + SHORT_CONFIG: linux_64_ + UPLOAD_PACKAGES: True + DOCKER_IMAGE: quay.io/condaforge/linux-anvil-cos7-x86_64 + os: ubuntu + - CONFIG: win_64_ + SHORT_CONFIG: win_64_ + UPLOAD_PACKAGES: True + os: windows + steps: + + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Build on Linux + if: matrix.os == 'ubuntu' + env: + CONFIG: ${{ matrix.CONFIG }} + UPLOAD_PACKAGES: ${{ matrix.UPLOAD_PACKAGES }} + DOCKER_IMAGE: ${{ matrix.DOCKER_IMAGE }} + CI: github_actions + UPLOAD_ON_BRANCH: main + BINSTAR_TOKEN: ${{ secrets.BINSTAR_TOKEN }} + shell: bash + run: | + echo "::group::Configure binfmt_misc" + docker run --rm --privileged multiarch/qemu-user-static:register --reset --credential yes + export FEEDSTOCK_NAME="$(basename $GITHUB_REPOSITORY)" + export GIT_BRANCH="$(basename $GITHUB_REF)" + if [[ "${GITHUB_EVENT_NAME}" == "pull_request" ]]; then + export IS_PR_BUILD="True" + else + export IS_PR_BUILD="False" + fi + echo "::endgroup::" + ./.scripts/run_docker_build.sh + + - name: Build on macOS + if: matrix.os == 'macos' + env: + CONFIG: ${{ matrix.CONFIG }} + UPLOAD_PACKAGES: ${{ matrix.UPLOAD_PACKAGES }} + CI: github_actions + UPLOAD_ON_BRANCH: main + BINSTAR_TOKEN: ${{ secrets.BINSTAR_TOKEN }} + shell: bash + run: | + export FEEDSTOCK_NAME="$(basename $GITHUB_REPOSITORY)" + export GIT_BRANCH="$(basename $GITHUB_REF)" + if [[ "${GITHUB_EVENT_NAME}" == "pull_request" ]]; then + export IS_PR_BUILD="True" + else + export IS_PR_BUILD="False" + fi + ./.scripts/run_osx_build.sh + + - name: Install Miniconda for windows + uses: conda-incubator/setup-miniconda@v2 + with: + miniforge-version: latest + miniforge-variant: Mambaforge + if: matrix.os == 'windows' + + - name: Build on windows + shell: cmd + run: | + call ".scripts\run_win_build.bat" + env: + PYTHONUNBUFFERED: 1 + CONFIG: ${{ matrix.CONFIG }} + CI: github_actions + UPLOAD_PACKAGES: ${{ matrix.UPLOAD_PACKAGES }} + UPLOAD_ON_BRANCH: main + BINSTAR_TOKEN: ${{ secrets.BINSTAR_TOKEN }} + if: matrix.os == 'windows' + - name: Prepare conda build artifacts + id: prepare-artifacts + shell: bash + if: ${{ always() }} + env: + CONFIG: ${{ matrix.CONFIG }} + SHORT_CONFIG: ${{ matrix.SHORT_CONFIG }} + OS: ${{ matrix.os }} + run: | + export CI=github_actions + export CI_RUN_ID=$GITHUB_RUN_ID + export FEEDSTOCK_NAME="$(basename $GITHUB_REPOSITORY)" + export ARTIFACT_STAGING_DIR="$GITHUB_WORKSPACE" + if [ $OS == "macos" ]; then + export CONDA_BLD_DIR="${MINIFORGE_HOME:-${HOME}/miniforge3}/conda-bld" + elif [ $OS == "windows" ]; then + export CONDA_BLD_DIR="${CONDA//\\//}/conda-bld" + else + export CONDA_BLD_DIR="build_artifacts" + fi + # Archive everything in CONDA_BLD_DIR except environments + # Archive the CONDA_BLD_DIR environments only when the job fails + # Use different prefix for successful and failed build artifacts + # so random failures don't prevent rebuilds from creating artifacts. + JOB_STATUS="${{ job.status }}" + if [ $JOB_STATUS == "failure" ]; then + export BLD_ARTIFACT_PREFIX="conda_artifacts" + export ENV_ARTIFACT_PREFIX="conda_envs" + else + export BLD_ARTIFACT_PREFIX="conda_pkgs" + fi + ./.scripts/create_conda_build_artifacts.sh + continue-on-error: true + + - name: Store conda build artifacts + uses: actions/upload-artifact@v3 + if: ${{ always() && steps.prepare-artifacts.outcome == 'success' }} + with: + name: ${{ steps.prepare-artifacts.outputs.BLD_ARTIFACT_NAME }} + path: ${{ steps.prepare-artifacts.outputs.BLD_ARTIFACT_PATH }} + retention-days: 14 + continue-on-error: true + + - name: Store conda build environment artifacts + uses: actions/upload-artifact@v3 + if: ${{ failure() && steps.prepare-artifacts.outcome == 'success' }} + with: + name: ${{ steps.prepare-artifacts.outputs.ENV_ARTIFACT_NAME }} + path: ${{ steps.prepare-artifacts.outputs.ENV_ARTIFACT_PATH }} + retention-days: 14 + continue-on-error: true \ No newline at end of file diff --git a/.github/workflows/webservices.yml b/.github/workflows/webservices.yml new file mode 100644 index 0000000..d6f06b5 --- /dev/null +++ b/.github/workflows/webservices.yml @@ -0,0 +1,13 @@ +on: repository_dispatch + +jobs: + webservices: + runs-on: ubuntu-latest + name: webservices + steps: + - name: webservices + id: webservices + uses: conda-forge/webservices-dispatch-action@main + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + rerendering_github_token: ${{ secrets.RERENDERING_GITHUB_TOKEN }} diff --git a/.scripts/build_steps.sh b/.scripts/build_steps.sh new file mode 100755 index 0000000..e10028d --- /dev/null +++ b/.scripts/build_steps.sh @@ -0,0 +1,84 @@ +#!/usr/bin/env bash + +# PLEASE NOTE: This script has been automatically generated by conda-smithy. Any changes here +# will be lost next time ``conda smithy rerender`` is run. If you would like to make permanent +# changes to this script, consider a proposal to conda-smithy so that other feedstocks can also +# benefit from the improvement. + +# -*- mode: jinja-shell -*- + +set -xeuo pipefail +export FEEDSTOCK_ROOT="${FEEDSTOCK_ROOT:-/home/conda/feedstock_root}" +source ${FEEDSTOCK_ROOT}/.scripts/logging_utils.sh + + +( endgroup "Start Docker" ) 2> /dev/null + +( startgroup "Configuring conda" ) 2> /dev/null + +export PYTHONUNBUFFERED=1 +export RECIPE_ROOT="${RECIPE_ROOT:-/home/conda/recipe_root}" +export CI_SUPPORT="${FEEDSTOCK_ROOT}/.ci_support" +export CONFIG_FILE="${CI_SUPPORT}/${CONFIG}.yaml" + +cat >~/.condarc < /dev/null + +if [[ -f "${FEEDSTOCK_ROOT}/LICENSE.txt" ]]; then + cp "${FEEDSTOCK_ROOT}/LICENSE.txt" "${RECIPE_ROOT}/recipe-scripts-license.txt" +fi + +if [[ "${BUILD_WITH_CONDA_DEBUG:-0}" == 1 ]]; then + if [[ "x${BUILD_OUTPUT_ID:-}" != "x" ]]; then + EXTRA_CB_OPTIONS="${EXTRA_CB_OPTIONS:-} --output-id ${BUILD_OUTPUT_ID}" + fi + conda debug "${RECIPE_ROOT}" -m "${CI_SUPPORT}/${CONFIG}.yaml" \ + ${EXTRA_CB_OPTIONS:-} \ + --clobber-file "${CI_SUPPORT}/clobber_${CONFIG}.yaml" + + # Drop into an interactive shell + /bin/bash +else + conda mambabuild "${RECIPE_ROOT}" -m "${CI_SUPPORT}/${CONFIG}.yaml" \ + --suppress-variables ${EXTRA_CB_OPTIONS:-} \ + --clobber-file "${CI_SUPPORT}/clobber_${CONFIG}.yaml" + + ( startgroup "Uploading packages" ) 2> /dev/null + + if [[ "${UPLOAD_PACKAGES}" != "False" ]] && [[ "${IS_PR_BUILD}" == "False" ]]; then + upload_package "${FEEDSTOCK_ROOT}" "${RECIPE_ROOT}" "${CONFIG_FILE}" + fi + + ( endgroup "Uploading packages" ) 2> /dev/null +fi + +( startgroup "Final checks" ) 2> /dev/null + +touch "${FEEDSTOCK_ROOT}/build_artifacts/conda-forge-build-done-${CONFIG}" \ No newline at end of file diff --git a/.scripts/create_conda_build_artifacts.sh b/.scripts/create_conda_build_artifacts.sh new file mode 100755 index 0000000..17ec086 --- /dev/null +++ b/.scripts/create_conda_build_artifacts.sh @@ -0,0 +1,113 @@ +#!/usr/bin/env bash + +# INPUTS (environment variables that need to be set before calling this script): +# +# CI (azure/github_actions/UNSET) +# CI_RUN_ID (unique identifier for the CI job run) +# FEEDSTOCK_NAME +# CONFIG (build matrix configuration string) +# SHORT_CONFIG (uniquely-shortened configuration string) +# CONDA_BLD_DIR (path to the conda-bld directory) +# ARTIFACT_STAGING_DIR (use working directory if unset) +# BLD_ARTIFACT_PREFIX (prefix for the conda build artifact name, skip if unset) +# ENV_ARTIFACT_PREFIX (prefix for the conda build environments artifact name, skip if unset) + +# OUTPUTS +# +# BLD_ARTIFACT_NAME +# BLD_ARTIFACT_PATH +# ENV_ARTIFACT_NAME +# ENV_ARTIFACT_PATH + +source .scripts/logging_utils.sh + +# DON'T do set -x, because it results in double echo-ing pipeline commands +# and that might end up inserting extraneous quotation marks in output variables +set -e + +# Check that the conda-build directory exists +if [ ! -d "$CONDA_BLD_DIR" ]; then + echo "conda-build directory does not exist" + exit 1 +fi + +# Set staging dir to the working dir, in Windows style if applicable +if [[ -z "${ARTIFACT_STAGING_DIR}" ]]; then + if pwd -W; then + ARTIFACT_STAGING_DIR=$(pwd -W) + else + ARTIFACT_STAGING_DIR=$PWD + fi +fi +echo "ARTIFACT_STAGING_DIR: $ARTIFACT_STAGING_DIR" + +FEEDSTOCK_ROOT=$(cd "$(dirname "$0")/.."; pwd;) +if [ -z ${FEEDSTOCK_NAME} ]; then + export FEEDSTOCK_NAME=$(basename ${FEEDSTOCK_ROOT}) +fi + +# Set a unique ID for the artifact(s), specialized for this particular job run +ARTIFACT_UNIQUE_ID="${CI_RUN_ID}_${CONFIG}" +if [[ ${#ARTIFACT_UNIQUE_ID} -gt 80 ]]; then + ARTIFACT_UNIQUE_ID="${CI_RUN_ID}_${SHORT_CONFIG}" +fi +echo "ARTIFACT_UNIQUE_ID: $ARTIFACT_UNIQUE_ID" + +# Set a descriptive ID for the archive(s), specialized for this particular job run +ARCHIVE_UNIQUE_ID="${CI_RUN_ID}_${CONFIG}" + +# Make the build artifact zip +if [[ ! -z "$BLD_ARTIFACT_PREFIX" ]]; then + export BLD_ARTIFACT_NAME="${BLD_ARTIFACT_PREFIX}_${ARTIFACT_UNIQUE_ID}" + export BLD_ARTIFACT_PATH="${ARTIFACT_STAGING_DIR}/${FEEDSTOCK_NAME}_${BLD_ARTIFACT_PREFIX}_${ARCHIVE_UNIQUE_ID}.zip" + + ( startgroup "Archive conda build directory" ) 2> /dev/null + + # Try 7z and fall back to zip if it fails (for cross-platform use) + if ! 7z a "$BLD_ARTIFACT_PATH" "$CONDA_BLD_DIR" '-xr!.git/' '-xr!_*_env*/' '-xr!*_cache/' -bb; then + pushd "$CONDA_BLD_DIR" + zip -r -y -T "$BLD_ARTIFACT_PATH" . -x '*.git/*' '*_*_env*/*' '*_cache/*' + popd + fi + + ( endgroup "Archive conda build directory" ) 2> /dev/null + + echo "BLD_ARTIFACT_NAME: $BLD_ARTIFACT_NAME" + echo "BLD_ARTIFACT_PATH: $BLD_ARTIFACT_PATH" + + if [[ "$CI" == "azure" ]]; then + echo "##vso[task.setVariable variable=BLD_ARTIFACT_NAME]$BLD_ARTIFACT_NAME" + echo "##vso[task.setVariable variable=BLD_ARTIFACT_PATH]$BLD_ARTIFACT_PATH" + elif [[ "$CI" == "github_actions" ]]; then + echo "BLD_ARTIFACT_NAME=$BLD_ARTIFACT_NAME" >> $GITHUB_OUTPUT + echo "BLD_ARTIFACT_PATH=$BLD_ARTIFACT_PATH" >> $GITHUB_OUTPUT + fi +fi + +# Make the environments artifact zip +if [[ ! -z "$ENV_ARTIFACT_PREFIX" ]]; then + export ENV_ARTIFACT_NAME="${ENV_ARTIFACT_PREFIX}_${ARTIFACT_UNIQUE_ID}" + export ENV_ARTIFACT_PATH="${ARTIFACT_STAGING_DIR}/${FEEDSTOCK_NAME}_${ENV_ARTIFACT_PREFIX}_${ARCHIVE_UNIQUE_ID}.zip" + + ( startgroup "Archive conda build environments" ) 2> /dev/null + + # Try 7z and fall back to zip if it fails (for cross-platform use) + if ! 7z a "$ENV_ARTIFACT_PATH" -r "$CONDA_BLD_DIR"/'_*_env*/' -bb; then + pushd "$CONDA_BLD_DIR" + zip -r -y -T "$ENV_ARTIFACT_PATH" . -i '*_*_env*/*' + popd + fi + + ( endgroup "Archive conda build environments" ) 2> /dev/null + + echo "ENV_ARTIFACT_NAME: $ENV_ARTIFACT_NAME" + echo "ENV_ARTIFACT_PATH: $ENV_ARTIFACT_PATH" + + if [[ "$CI" == "azure" ]]; then + echo "##vso[task.setVariable variable=ENV_ARTIFACT_NAME]$ENV_ARTIFACT_NAME" + echo "##vso[task.setVariable variable=ENV_ARTIFACT_PATH]$ENV_ARTIFACT_PATH" + elif [[ "$CI" == "github_actions" ]]; then + echo "ENV_ARTIFACT_NAME=$ENV_ARTIFACT_NAME" >> $GITHUB_OUTPUT + echo "ENV_ARTIFACT_PATH=$ENV_ARTIFACT_PATH" >> $GITHUB_OUTPUT + fi +fi \ No newline at end of file diff --git a/.scripts/logging_utils.sh b/.scripts/logging_utils.sh new file mode 100644 index 0000000..aff009f --- /dev/null +++ b/.scripts/logging_utils.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +# Provide a unified interface for the different logging +# utilities CI providers offer. If unavailable, provide +# a compatible fallback (e.g. bare `echo xxxxxx`). + +function startgroup { + # Start a foldable group of log lines + # Pass a single argument, quoted + case ${CI:-} in + azure ) + echo "##[group]$1";; + travis ) + echo "$1" + echo -en 'travis_fold:start:'"${1// /}"'\r';; + github_actions ) + echo "::group::$1";; + * ) + echo "$1";; + esac +} 2> /dev/null + +function endgroup { + # End a foldable group of log lines + # Pass a single argument, quoted + + case ${CI:-} in + azure ) + echo "##[endgroup]";; + travis ) + echo -en 'travis_fold:end:'"${1// /}"'\r';; + github_actions ) + echo "::endgroup::";; + esac +} 2> /dev/null diff --git a/.scripts/run_docker_build.sh b/.scripts/run_docker_build.sh new file mode 100755 index 0000000..71f65be --- /dev/null +++ b/.scripts/run_docker_build.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash + +# PLEASE NOTE: This script has been automatically generated by conda-smithy. Any changes here +# will be lost next time ``conda smithy rerender`` is run. If you would like to make permanent +# changes to this script, consider a proposal to conda-smithy so that other feedstocks can also +# benefit from the improvement. + +source .scripts/logging_utils.sh + +( startgroup "Configure Docker" ) 2> /dev/null + +set -xeo pipefail + +THISDIR="$( cd "$( dirname "$0" )" >/dev/null && pwd )" +PROVIDER_DIR="$(basename $THISDIR)" + +FEEDSTOCK_ROOT="$( cd "$( dirname "$0" )/.." >/dev/null && pwd )" +RECIPE_ROOT="${FEEDSTOCK_ROOT}/.conda/recipe" + +if [ -z ${FEEDSTOCK_NAME} ]; then + export FEEDSTOCK_NAME=$(basename ${FEEDSTOCK_ROOT}) +fi + +docker info + +# In order for the conda-build process in the container to write to the mounted +# volumes, we need to run with the same id as the host machine, which is +# normally the owner of the mounted volumes, or at least has write permission +export HOST_USER_ID=$(id -u) +# Check if docker-machine is being used (normally on OSX) and get the uid from +# the VM +if hash docker-machine 2> /dev/null && docker-machine active > /dev/null; then + export HOST_USER_ID=$(docker-machine ssh $(docker-machine active) id -u) +fi + +ARTIFACTS="$FEEDSTOCK_ROOT/build_artifacts" + +if [ -z "$CONFIG" ]; then + set +x + FILES=`ls .ci_support/linux_*` + CONFIGS="" + for file in $FILES; do + CONFIGS="${CONFIGS}'${file:12:-5}' or "; + done + echo "Need to set CONFIG env variable. Value can be one of ${CONFIGS:0:-4}" + exit 1 +fi + +if [ -z "${DOCKER_IMAGE}" ]; then + SHYAML_INSTALLED="$(shyaml -h || echo NO)" + if [ "${SHYAML_INSTALLED}" == "NO" ]; then + echo "WARNING: DOCKER_IMAGE variable not set and shyaml not installed. Trying to parse with coreutils" + DOCKER_IMAGE=$(cat .ci_support/${CONFIG}.yaml | grep '^docker_image:$' -A 1 | tail -n 1 | cut -b 3-) + if [ "${DOCKER_IMAGE}" = "" ]; then + echo "No docker_image entry found in ${CONFIG}. Falling back to quay.io/condaforge/linux-anvil-comp7" + DOCKER_IMAGE="quay.io/condaforge/linux-anvil-comp7" + fi + else + DOCKER_IMAGE="$(cat "${FEEDSTOCK_ROOT}/.ci_support/${CONFIG}.yaml" | shyaml get-value docker_image.0 quay.io/condaforge/linux-anvil-comp7 )" + fi +fi + +mkdir -p "$ARTIFACTS" +DONE_CANARY="$ARTIFACTS/conda-forge-build-done-${CONFIG}" +rm -f "$DONE_CANARY" + +# Allow people to specify extra default arguments to `docker run` (e.g. `--rm`) +DOCKER_RUN_ARGS="${CONDA_FORGE_DOCKER_RUN_ARGS}" +if [ -z "${CI}" ]; then + DOCKER_RUN_ARGS="-it ${DOCKER_RUN_ARGS}" +fi + +( endgroup "Configure Docker" ) 2> /dev/null + +( startgroup "Start Docker" ) 2> /dev/null + +export UPLOAD_PACKAGES="${UPLOAD_PACKAGES:-True}" +export IS_PR_BUILD="${IS_PR_BUILD:-False}" +docker pull "${DOCKER_IMAGE}" +docker run ${DOCKER_RUN_ARGS} \ + -v "${RECIPE_ROOT}":/home/conda/recipe_root:rw,z,delegated \ + -v "${FEEDSTOCK_ROOT}":/home/conda/feedstock_root:rw,z,delegated \ + -e CONFIG \ + -e HOST_USER_ID \ + -e UPLOAD_PACKAGES \ + -e IS_PR_BUILD \ + -e GIT_BRANCH \ + -e UPLOAD_ON_BRANCH \ + -e CI \ + -e FEEDSTOCK_NAME \ + -e CPU_COUNT \ + -e BUILD_WITH_CONDA_DEBUG \ + -e BUILD_OUTPUT_ID \ + -e BINSTAR_TOKEN \ + "${DOCKER_IMAGE}" \ + bash \ + "/home/conda/feedstock_root/${PROVIDER_DIR}/build_steps.sh" + +# verify that the end of the script was reached +test -f "$DONE_CANARY" + +# This closes the last group opened in `build_steps.sh` +( endgroup "Final checks" ) 2> /dev/null \ No newline at end of file diff --git a/.scripts/run_win_build.bat b/.scripts/run_win_build.bat new file mode 100755 index 0000000..a6cb538 --- /dev/null +++ b/.scripts/run_win_build.bat @@ -0,0 +1,113 @@ +:: PLEASE NOTE: This script has been automatically generated by conda-smithy. Any changes here +:: will be lost next time ``conda smithy rerender`` is run. If you would like to make permanent +:: changes to this script, consider a proposal to conda-smithy so that other feedstocks can also +:: benefit from the improvement. + +:: Note: we assume a Miniforge installation is available + +:: INPUTS (required environment variables) +:: CONFIG: name of the .ci_support/*.yaml file for this job +:: CI: azure, github_actions, or unset +:: UPLOAD_PACKAGES: true or false +:: UPLOAD_ON_BRANCH: true or false + +setlocal enableextensions enabledelayedexpansion + +call :start_group "Configuring conda" + +:: Activate the base conda environment +call activate base + +:: Provision the necessary dependencies to build the recipe later +echo Installing dependencies +mamba.exe install "python=3.10" pip mamba conda-build boa conda-forge-ci-setup=3 -c conda-forge --strict-channel-priority --yes +if !errorlevel! neq 0 exit /b !errorlevel! + +:: Set basic configuration +echo Setting up configuration +setup_conda_rc .\ ".\.conda/recipe" .\.ci_support\%CONFIG%.yaml +if !errorlevel! neq 0 exit /b !errorlevel! +echo Running build setup +CALL run_conda_forge_build_setup + + +if !errorlevel! neq 0 exit /b !errorlevel! + +if EXIST LICENSE.txt ( + echo Copying feedstock license + copy LICENSE.txt ".conda/recipe\\recipe-scripts-license.txt" +) +if NOT [%HOST_PLATFORM%] == [%BUILD_PLATFORM%] ( + set "EXTRA_CB_OPTIONS=%EXTRA_CB_OPTIONS% --no-test" +) + +call :end_group + +:: Build the recipe +echo Building recipe +conda.exe mambabuild ".conda/recipe" -m .ci_support\%CONFIG%.yaml --suppress-variables %EXTRA_CB_OPTIONS% +if !errorlevel! neq 0 exit /b !errorlevel! + +:: Prepare some environment variables for the upload step +if /i "%CI%" == "github_actions" ( + set "FEEDSTOCK_NAME=%GITHUB_REPOSITORY:*/=%" + set "GIT_BRANCH=%GITHUB_REF:refs/heads/=%" + if /i "%GITHUB_EVENT_NAME%" == "pull_request" ( + set "IS_PR_BUILD=True" + ) else ( + set "IS_PR_BUILD=False" + ) + set "TEMP=%RUNNER_TEMP%" +) +if /i "%CI%" == "azure" ( + set "FEEDSTOCK_NAME=%BUILD_REPOSITORY_NAME:*/=%" + set "GIT_BRANCH=%BUILD_SOURCEBRANCHNAME%" + if /i "%BUILD_REASON%" == "PullRequest" ( + set "IS_PR_BUILD=True" + ) else ( + set "IS_PR_BUILD=False" + ) + set "TEMP=%UPLOAD_TEMP%" +) +set "UPLOAD_ON_BRANCH=main" +:: Note, this needs GIT_BRANCH too + +:: Validate + +if /i "%UPLOAD_PACKAGES%" == "true" ( + if /i "%IS_PR_BUILD%" == "false" ( + call :start_group "Uploading packages" + if not exist "%TEMP%\" md "%TEMP%" + set "TMP=%TEMP%" + upload_package .\ ".\.conda/recipe" .ci_support\%CONFIG%.yaml + if !errorlevel! neq 0 exit /b !errorlevel! + call :end_group + ) +) + +exit + +:: Logging subroutines + +:start_group +if /i "%CI%" == "github_actions" ( + echo ::group::%~1 + exit /b +) +if /i "%CI%" == "azure" ( + echo ##[group]%~1 + exit /b +) +echo %~1 +exit /b + +:end_group +if /i "%CI%" == "github_actions" ( + echo ::endgroup:: + exit /b +) +if /i "%CI%" == "azure" ( + echo ##[endgroup] + exit /b +) +exit /b \ No newline at end of file