diff --git a/.github/actions/openvic-sim-build/action.yml b/.github/actions/openvic-sim-build/action.yml new file mode 100644 index 000000000..ec8a8d660 --- /dev/null +++ b/.github/actions/openvic-sim-build/action.yml @@ -0,0 +1,106 @@ +name: Build OpenVic-Simulation +description: Setup and Build OpenVic-Simulation with the provided options + +inputs: + identifier: + description: Identifier of this build + type: string + target: + description: Target type to build for + type: choice + options: [template_release, template_debug, editor] + platform: + description: Platform to build for + type: choice + options: [windows, linux, macos] + arch: + description: Architecture to build for + type: choice + options: [x86_64, universal] + scons-flags: + description: Additional flags to send to SCons + required: false + default: 'build_ovsim_benchmarks=yes' + type: string + build-library: + description: Whether to build the library file + default: true + type: boolean + cache-base-branch: + description: | + Branch to base the cache upon + required: false + default: 'master' + type: string + disable-cache: + description: Whether to disable the build cache + default: false + type: boolean + +runs: + using: composite + steps: + - name: Setup build cache + uses: OpenVicProject/openvic-cache@master + if: ${{ !inputs.disable-cache }} + with: + cache-name: ${{ inputs.identifier }} + base-branch: ${{ inputs.cache-base-branch }} + continue-on-error: true + + - name: Set up Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + with: + python-version: "3.x" + + - name: Set up SCons + shell: bash + run: | + python -c "import sys; print(sys.version)" + python -m pip install scons + scons --version + + - name: Install APT dependencies + if: ${{ inputs.platform == 'linux' }} + uses: awalsh128/cache-apt-pkgs-action@acb598e5ddbc6f68a970c5da0688d2f3a9f04d05 # v1.6.0 + with: + packages: build-essential pkg-config libtbb-dev + + - name: Install and Set g++ to version 13 + if: ${{ inputs.platform == 'linux' }} + shell: sh + run: | + g++ --version + sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y + sudo apt update -y + sudo apt install g++-13 + sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 13 + sudo update-alternatives --set g++ /usr/bin/g++-13 + g++ --version + + - name: Compile with SCons + uses: OpenVicProject/openvic-build@master + with: + platform: ${{ inputs.platform }} + target: ${{ inputs.target }} + sconsflags: arch=${{ inputs.arch }} ${{ inputs.build-library && 'build_ovsim_library=yes' }} ${{ inputs.scons-flags }} + + - name: Delete compilation files + if: ${{ inputs.platform == 'windows' }} + shell: pwsh + run: | + Remove-Item bin/* -Include *.exp,*.pdb -Force + + - name: Upload library artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: ${{ github.event.repository.name }}-${{ inputs.identifier }}-library + path: | + ${{ github.workspace }}/bin/libopenvic-simulation.* + + - name: Upload executable artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: ${{ github.event.repository.name }}-${{ inputs.identifier }}-executable + path: | + ${{ github.workspace }}/bin/openvic-simulation.headless.* diff --git a/.github/actions/openvic-sim-release/action.yml b/.github/actions/openvic-sim-release/action.yml new file mode 100644 index 000000000..1e1fbbf5f --- /dev/null +++ b/.github/actions/openvic-sim-release/action.yml @@ -0,0 +1,297 @@ +name: Release OpenVic-Simulation +description: Setup, Build, and Release OpenVic-Simulation + +inputs: + tag-name: + description: 'Name to assign to the tag (default: github.ref)' + default: ${{ github.ref }} + type: string + target-repo: + description: Repository to publish this release to + default: 'OpenVic-Simulation' + type: string + to-ref: + description: 'Tag/Commit to publish this release to (default: github.ref)' + default: ${{ github.ref }} + type: string + from-ref: + description: Tag/Commit to source the release notes from + type: string + required: true + from-tag: + description: 'Tag name being sourced from (default: from-ref)' + default: '' + type: string + nightly-release: + description: Whether the release is a nightly build + type: boolean + default: false + snapshot-release: + description: Whether the release is a snapshot release + type: boolean + default: false + latest: + description: Latest + type: boolean + default: false + prerelease: + description: Pre-release + type: boolean + required: true + src-token: + description: Github token for source repository + required: true + target-token: + description: Github token for target repository + required: false + default: '' + +runs: + using: composite + steps: + - name: Setup regex variables + shell: bash + run: | + echo "SEMVER_REGEX=^v(0|[1-9][0-9]*)((\.(0|[1-9][0-9]*)){1,2})(-(alpha|beta|rc)\.([1-9][0-9]*))?$" >> $GITHUB_ENV + echo "SEMVER_SNAPSHOT_REGEX=^v(0|[1-9][0-9]*)((\.(0|[1-9][0-9]*)){1,2})-(snapshot|snapshot\.dev)\.([1-9][0-9]*)\+([0-9a-fA-F]{40})$" >> $GITHUB_ENV + echo "SEMVER_NIGHTLY_REGEX=^v(0|[1-9][0-9]*)((\.(0|[1-9][0-9]*)){1,2})-(nightly\.([1-9]([0-9]){3})\.(([0-9]){2})\.(([0-9]){2}))\+([0-9a-fA-F]{40})$" >> $GITHUB_ENV + echo "SHA_REGEX=^[0-9a-fA-F]{40}$" >> $GITHUB_ENV + + - name: Validate input values + shell: bash + env: + INPUTS_TAG_NAME: ${{ inputs.tag-name }} + INPUTS_TARGET_REPO: ${{ inputs.target-repo }} + INPUTS_TO_REF: ${{ inputs.to-ref }} + INPUTS_FROM_REF: ${{ inputs.from-ref }} + INPUTS_FROM_TAG: ${{ inputs.from-tag }} + INPUTS_NIGHTLY_RELEASE: ${{ inputs.nightly-release }} + INPUTS_SNAPSHOT_RELEASE: ${{ inputs.snapshot-release }} + INPUTS_LATEST: ${{ inputs.latest }} + INPUTS_PRERELEASE: ${{ inputs.prerelease }} + INPUTS_SRC_TOKEN: ${{ inputs.src-token }} + INPUTS_TARGET_TOKEN: ${{ inputs.target-token }} + run: | + # Can report error for every validation check + EXIT_STATUS=0 + + validate_non_empty () { + [[ -n ${1-} ]] && return + echo "::error::${2-parameter} is empty." + EXIT_STATUS=1 + false + } + + validate_semver () { + if validate_non_empty "$1" "${2-}"; then + [[ ${1-} =~ $SEMVER_REGEX ]] && return + [[ ${1-} =~ $SEMVER_SNAPSHOT_REGEX ]] && return + [[ ${1-} =~ $SEMVER_NIGHTLY_REGEX ]] && return + fi + + if [[ -n ${2-} ]]; then + echo "::error::$2 is not a valid semver string for versioning starting with v. Valid prerelease values are 'alpha', 'beta', 'rc', 'snapshot', 'snapshot.dev', and 'nightly'. A count value must follow all but 'nightly' prerelease tags, starting from 1. 'nightly' must include the date in YYYY.MM.DD format. 'snapshot', 'snapshot.dev', 'nightly' must include the full commit SHA as a build string." + EXIT_STATUS=1 + fi + false + } + + validate_ref () { + local VALUE=${1#'refs/tags/'} + + if validate_non_empty "$VALUE" "${2-}"; then + validate_semver "$VALUE" && return + [[ ${VALUE:-} =~ $SHA_REGEX ]] && return + fi + + echo "::error::${2-parameter} is not a git commit SHA or valid semver string for versioning starting with v. Valid prerelease values are 'alpha', 'beta', 'rc', 'snapshot', 'snapshot.dev', and 'nightly'. A count value must follow all but 'nightly' prerelease tags, starting from 1. 'nightly' must include the date in YYYY.MM.DD format. 'snapshot', 'snapshot.dev', 'nightly' must include the full commit SHA as a build string." + EXIT_STATUS=1 + false + } + + if [[ $INPUTS_TAG_NAME == refs/tags/* ]]; then + INPUTS_TAG_NAME=${INPUTS_TAG_NAME#'refs/tags/'} + fi + + validate_semver "$INPUTS_TAG_NAME" "inputs.tag-name" + + if [[ "$GITHUB_REPOSITORY_OWNER/$INPUTS_TARGET_REPO" != $GITHUB_REPOSITORY ]]; then + if ! validate_non_empty "$INPUTS_TARGET_REPO" "inputs.target-repo" && [[ -z $INPUTS_TARGET_TOKEN ]]; then + echo "::error::inputs.target-repo is set to a different repository and the inputs.target-token is not set." + EXIT_STATUS=1 + fi + fi + + validate_ref "$INPUTS_TO_REF" "inputs.to-ref" + + validate_ref "$INPUTS_FROM_REF" "inputs.from-ref" + + if [[ -n $INPUTS_FROM_TAG ]]; then + validate_ref "$INPUTS_FROM_TAG" "inputs.from-tag" + fi + + validate_non_empty "$INPUTS_SRC_TOKEN" "inputs.src-token" + + exit $EXIT_STATUS + + - name: Copy src-token to env.TARGET_TOKEN + if: format('{0}/{1}', github.repository_owner, inputs.target-repo) == github.repository + shell: bash + env: + INPUTS_SRC_TOKEN: ${{ inputs.src-token }} + run: echo "TARGET_TOKEN=$INPUTS_SRC_TOKEN" >> $GITHUB_ENV + + - name: Copy target-token to env.TARGET_TOKEN + if: format('{0}/{1}', github.repository_owner, inputs.target-repo) != github.repository + shell: bash + env: + INPUTS_TARGET_TOKEN: ${{ inputs.target-token }} + run: echo "TARGET_TOKEN=$INPUTS_TARGET_TOKEN" >> $GITHUB_ENV + + - name: Set TO_TAG from to-ref + if: inputs.tag-name == inputs.to-ref + shell: bash + env: + INPUTS_TO_REF: ${{ inputs.to-ref }} + run: echo "TO_TAG=${INPUTS_TO_REF#'refs/tags/'}" >> $GITHUB_ENV + + - name: Set TO_TAG from tag-name + if: inputs.tag-name != inputs.to-ref + shell: bash + env: + INPUTS_TAG_NAME: ${{ inputs.tag-name }} + run: echo "TO_TAG=$INPUTS_TAG_NAME" >> $GITHUB_ENV + + - name: Build Release Notes + if: inputs.snapshot-release == 'false' && inputs.nightly-release == 'false' + uses: mikepenz/release-changelog-builder-action@348e88fab4c37338b1e803ceb2d4a7a5db6c0833 # v6.2.2 + env: + GITHUB_TOKEN: ${{ inputs.src-token }} + with: + configuration: "${{ github.action_path }}/release-notes-configuration.json" + toTag: ${{ inputs.tag-name == inputs.to-ref && env.TO_TAG || inputs.to-ref }} + fromTag: ${{ inputs.from-ref }} + outputFile: release-notes.md + + - name: Build Snapshot Release Notes + if: inputs.snapshot-release == 'true' && inputs.nightly-release == 'false' + uses: mikepenz/release-changelog-builder-action@348e88fab4c37338b1e803ceb2d4a7a5db6c0833 # v6.2.2 + env: + GITHUB_TOKEN: ${{ inputs.src-token }} + with: + configuration: "${{ github.action_path }}/snapshot-release-notes-configuration.json" + toTag: ${{ inputs.tag-name == inputs.to-ref && env.TO_TAG || inputs.to-ref }} + fromTag: ${{ inputs.from-ref }} + outputFile: release-notes.md + + - name: Build Nightly Release Notes + if: inputs.nightly-release == 'true' && inputs.snapshot-release == 'false' + uses: mikepenz/release-changelog-builder-action@348e88fab4c37338b1e803ceb2d4a7a5db6c0833 # v6.2.2 + env: + GITHUB_TOKEN: ${{ inputs.src-token }} + with: + configuration: "${{ github.action_path }}/nightly-release-notes-configuration.json" + toTag: ${{ inputs.tag-name == inputs.to-ref && env.TO_TAG || inputs.to-ref }} + fromTag: ${{ inputs.from-ref }} + outputFile: release-notes.md + + - name: Create release tag and name and set release name in release-notes.md + shell: bash + env: + INPUTS_FROM_TAG_OR_FROM_REF: ${{ inputs.from-tag || inputs.from-ref }} + run: | + if [[ $TO_TAG =~ $SEMVER_REGEX ]]; then + PRERELEASE_TYPE=${BASH_REMATCH[6]} + PRERELEASE_VERSION=${BASH_REMATCH[7]} + + if [[ $PRERELEASE_TYPE == 'rc' ]]; then + PRERELEASE_NAME="Release Candidate" + else + PRERELEASE_NAME=${PRERELEASE_TYPE@u} + fi + + PRERELEASE_VERSION_DATE=$PRERELEASE_VERSION + elif [[ $TO_TAG =~ $SEMVER_SNAPSHOT_REGEX ]]; then + PRERELEASE_TYPE=${BASH_REMATCH[5]} + PRERELEASE_VERSION=${BASH_REMATCH[6]} + PRERELEASE_HASH=${BASH_REMATCH[7]} + + if [[ $PRERELEASE_TYPE == 'snapshot.dev' ]]; then + PRERELEASE_NAME="Dev Snapshot" + else + PRERELEASE_NAME=${PRERELEASE_TYPE@u} + fi + + PRERELEASE_VERSION_DATE=$PRERELEASE_VERSION + elif [[ $TO_TAG =~ $SEMVER_NIGHTLY_REGEX ]]; then + PRERELEASE_TYPE=nightly + PRERELEASE_YEAR=${BASH_REMATCH[6]} + PRERELEASE_MONTH=${BASH_REMATCH[8]} + PRERELEASE_DAY=${BASH_REMATCH[10]} + PRERELEASE_HASH=${BASH_REMATCH[12]} + PRERELEASE_NAME=${PRERELEASE_TYPE@u} + + PRERELEASE_VERSION_DATE="$PRERELEASE_YEAR.$PRERELEASE_MONTH.$PRERELEASE_DAY" + fi + + VERSION_CORE="${BASH_REMATCH[1]}${BASH_REMATCH[2]}" + + RELEASE_NAME="$(basename "$GITHUB_REPOSITORY") $(xargs <<< "$VERSION_CORE $PRERELEASE_NAME $PRERELEASE_VERSION_DATE")" + echo "RELEASE_NAME=$RELEASE_NAME" >> $GITHUB_ENV + + # Keep up to date with .github/actions/openvic-sim-release release-notes configs + sed -i "s/<>/$RELEASE_NAME/g" release-notes.md + sed -i "s/<>/$INPUTS_FROM_TAG_OR_FROM_REF/g" release-notes.md + + if [[ $INPUTS_FROM_TAG_OR_FROM_REF =~ $SHA_REGEX ]]; then + RELEASE_OR_COMMIT_PATH=commit + else + RELEASE_OR_COMMIT_PATH=releases\\/tag + fi + + sed -i "s/<>/$RELEASE_OR_COMMIT_PATH/g" release-notes.md + + - name: Replace <> in release-notes.md + shell: bash + run: sed -i "s/<>/$(sed 's;\/;\\\/;g' <<< "$GITHUB_REPOSITORY")/g" release-notes.md + + - name: Make library directory + shell: sh + run: mkdir "$GITHUB_WORKSPACE/library/" + + - name: Download library assets + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + path: "${{ github.workspace }}/library" + pattern: ${{ github.event.repository.name }}-*-library + merge-multiple: true + + - name: Download executable assets + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + pattern: ${{ github.event.repository.name }}-*-executable + merge-multiple: true + + - name: Zip library assets + uses: thedoctor0/zip-release@b57d897cb5d60cb78b51a507f63fa184cfe35554 # v0.7.6 + with: + type: "zip" + filename: libopenvic-simulation.zip + path: library + + - name: Create and upload asset + uses: ncipollo/release-action@339a81892b84b4eeb0f6e744e4574d79d0d9b8dd # v1.21.0 + with: + allowUpdates: true + artifacts: "libopenvic-simulation.zip,openvic-simulation.headless.**" + omitNameDuringUpdate: true + omitBodyDuringUpdate: true + name: "${{ env.RELEASE_NAME || '' }}" + tag: "${{ env.TO_TAG || '' }}" + commit: "${{ format('{0}/{1}', github.repository_owner, inputs.target-repo) == github.repository && !contains(inputs.to-ref, '.') && inputs.to-ref || '' }}" + bodyFile: "release-notes.md" + makeLatest: ${{ inputs.latest }} + prerelease: ${{ inputs.prerelease }} + draft: ${{ inputs.snapshot-release == 'false' && inputs.nightly-release == 'false' }} + repo: "${{ inputs.target-repo }}" + token: ${{ env.TARGET_TOKEN }} diff --git a/.github/actions/openvic-sim-release/nightly-release-notes-configuration.json b/.github/actions/openvic-sim-release/nightly-release-notes-configuration.json new file mode 100644 index 000000000..7ed107f64 --- /dev/null +++ b/.github/actions/openvic-sim-release/nightly-release-notes-configuration.json @@ -0,0 +1,40 @@ +{ + "base_branches": [ + "master" + ], + "custom_placeholders": [ + { + "comment": "Keep up to date with .github/workflows/nightly-releases.yml", + "name": "COMMIT_GENERATED_LINE", + "source": "TO_TAG", + "transformer": { + "method": "regexr", + "pattern": "([a-zA-Z0-9]{40})", + "target": "Generated from: <>@$1\n" + } + } + ], + "categories": [ + { + "title": "### Enhancements & Features", + "labels": [ + "enhancement" + ], + "exhaustive": true, + "consume": true + }, + { + "title": "### Bug Fixes", + "labels": [ + "bug" + ], + "exhaustive": true, + "consume": true + } + ], + "template": "# Release Notes for <>\n#{{COMMIT_GENERATED_LINE}}## Changelog since [<>](https://github.com/<>/<>/#{{FROM_TAG}})\n#{{CHANGELOG}}\n**Full Changelog**: #{{RELEASE_DIFF}}", + "empty_template": "# Release Notes for <>\n#{{COMMIT_GENERATED_LINE}}### No Pull Requests since [<>](https://github.com/<>/<>/#{{FROM_TAG}})\n\n**Full Changelog**: #{{RELEASE_DIFF}}", + "pr_template": "* #{{TITLE}} by @#{{AUTHOR}} in #{{URL}}", + "max_pull_requests": 1000, + "max_back_track_time_days": 365 +} \ No newline at end of file diff --git a/.github/actions/openvic-sim-release/release-notes-configuration.json b/.github/actions/openvic-sim-release/release-notes-configuration.json new file mode 100644 index 000000000..6705cd9c0 --- /dev/null +++ b/.github/actions/openvic-sim-release/release-notes-configuration.json @@ -0,0 +1,35 @@ +{ + "base_branches": [ + "master" + ], + "tag_resolver": { + "method": "sort", + "filter": { + "method": "regexr", + "pattern": "(\\d+\\.\\d+(?:\\.\\d+)?)(?:-((alpha|beta|rc)\\.(\\d+)))?" + } + }, + "categories": [ + { + "title": "### Enhancements & Features", + "labels": [ + "enhancement" + ], + "exhaustive": true, + "consume": true + }, + { + "title": "### Bug Fixes", + "labels": [ + "bug" + ], + "exhaustive": true, + "consume": true + } + ], + "template": "# Release Notes for <>\n## Changelog since [#{{FROM_TAG}}](https://github.com/<>/<>/#{{FROM_TAG}})\n#{{CHANGELOG}}\n\n**Full Changelog**: #{{RELEASE_DIFF}}", + "empty_template": "# Release Notes for <>\n### No Pull Requests since [#{{FROM_TAG}}](https://github.com/<>/<>/#{{FROM_TAG}})\n\n**Full Changelog**: #{{RELEASE_DIFF}}", + "pr_template": "* #{{TITLE}} by @#{{AUTHOR}} in #{{URL}}", + "max_pull_requests": 1000, + "max_back_track_time_days": 365 +} \ No newline at end of file diff --git a/.github/actions/openvic-sim-release/snapshot-release-notes-configuration.json b/.github/actions/openvic-sim-release/snapshot-release-notes-configuration.json new file mode 100644 index 000000000..4bc9059e3 --- /dev/null +++ b/.github/actions/openvic-sim-release/snapshot-release-notes-configuration.json @@ -0,0 +1,28 @@ +{ + "base_branches": [ + "master" + ], + "categories": [ + { + "title": "### Enhancements & Features", + "labels": [ + "enhancement" + ], + "exhaustive": true, + "consume": true + }, + { + "title": "### Bug Fixes", + "labels": [ + "bug" + ], + "exhaustive": true, + "consume": true + } + ], + "template": "# Release Notes for <>\n## Changelog since [#{{FROM_TAG}}](https://github.com/<>/<>/#{{FROM_TAG}})\n#{{CHANGELOG}}\n**Full Changelog**: #{{RELEASE_DIFF}}", + "empty_template": "# Release Notes for <>\n### No Pull Requests since [#{{FROM_TAG}}](https://github.com/<>/<>/#{{FROM_TAG}})\n\n**Full Changelog**: #{{RELEASE_DIFF}}", + "pr_template": "* #{{TITLE}} by @#{{AUTHOR}} in #{{URL}}", + "max_pull_requests": 1000, + "max_back_track_time_days": 365 +} \ No newline at end of file diff --git a/.github/changed-files.yml b/.github/changed-files.yml new file mode 100644 index 000000000..a532b7f13 --- /dev/null +++ b/.github/changed-files.yml @@ -0,0 +1,19 @@ +# We lack a convenient means of gathering *all* the changes when specializations are passed, so +# a catch-all variable is the easiest workaround. +everything: + - "**" + +# Determines if build actions should occur after static checks are ran. Broadly speaking, these +# files changing would result in SCons rebuilding the engine, or are otherwise pertinent to the +# buildsystem itself. +sources: + - .github/{actions/*,workflows}/*.yml + - "**/{SConstruct,SCsub,*.py}" + - "**/*.{hpp,cpp,inc}" + - scripts + - deps/** + - tests/** + +# Determines which files are appropriate for running clangd-tidy checks on. +clangd: + - "**/*.{hpp,cpp,inc}" \ No newline at end of file diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index d74e650d4..b4ad9c736 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -1,54 +1,94 @@ name: 🖥️ Builds -on: [push, pull_request, merge_group] - -env: - GH_BASE_BRANCH: master +on: + push: + branches: ['master'] + paths: + - '.github/workflows/builds.yml' + - '.github/actions/openvic-sim-build/action.yml' + - '**/{SConstruct,SCsub,*.py}' + - '**/*.{hpp,cpp,inc}' + - 'scripts' + - 'deps/**' + - 'tests/**' + - 'AUTHORS.md' + - 'COPYRIGHT' + - 'LICENSE.md' + - '.pre-commit-config.yaml' + - 'pyproject.toml' + - '.clang-format' + - '.clang-tidy' + - '.gitmodules' + pull_request: + paths: + - '.github/workflows/builds.yml' + - '.github/actions/openvic-sim-build/action.yml' + - '**/{SConstruct,SCsub,*.py}' + - '**/*.{hpp,cpp,inc}' + - 'scripts' + - 'deps/**' + - 'tests/**' + - 'AUTHORS.md' + - 'COPYRIGHT' + - 'LICENSE.md' + - '.pre-commit-config.yaml' + - 'pyproject.toml' + - '.clang-format' + - '.clang-tidy' + - '.gitmodules' + merge_group: + workflow_dispatch: concurrency: - group: ${{ github.workflow }}|${{ github.ref_name }} - cancel-in-progress: true + group: ${{ github.workflow }}|${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +permissions: {} jobs: - static-checks: + static-checks-builds: name: Code style, file formatting, and docs - runs-on: ubuntu-24.04 + runs-on: ubuntu-latest + if: github.run_attempt > 1 || github.event_name == 'workflow_dispatch' || !vars.DISABLE_BUILDS + outputs: + changed-files: '"${{ steps.changed-files.outputs.clangd_all_changed_files }}"' # Wrap with quotes to bookend internal quote separators. + sources-changed: ${{ steps.changed-files.outputs.sources_any_changed }} steps: - name: Checkout project - uses: actions/checkout@v4.1.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: - fetch-depth: 2 + fetch-depth: 0 # Treeless clone. Slightly less performant than a shallow clone, but makes finding diffs instantaneous. + filter: tree:0 # See: https://github.blog/open-source/git/get-up-to-speed-with-partial-clone-and-shallow-clone/ + persist-credentials: false - name: Install APT dependencies - uses: awalsh128/cache-apt-pkgs-action@latest + uses: awalsh128/cache-apt-pkgs-action@acb598e5ddbc6f68a970c5da0688d2f3a9f04d05 # v1.6.0 with: packages: libxml2-utils - name: Get changed files - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - git config diff.wsErrorHighlight all - if [ "${{ github.event_name }}" == "pull_request" -o "${{ github.event.forced }}" == "true" -o "${{ github.event.created }}" == "true" ]; then - files=$(git diff-tree --no-commit-id --name-only -r HEAD^1..HEAD 2> /dev/null || true) - elif [ "${{ github.event_name }}" == "push" -a "${{ github.event.created }}" == "false" ]; then - files=$(git diff-tree --no-commit-id --name-only -r ${{ github.event.before }}..${{ github.event.after }} 2> /dev/null || true) - fi - echo "$files" >> changed.txt - cat changed.txt - files=$(echo "$files" | xargs -I {} sh -c 'echo "\"./{}\""' | tr '\n' ' ') - echo "CHANGED_FILES=$files" >> $GITHUB_ENV - - - name: Style checks via pre-commit - uses: pre-commit/action@v3.0.1 + id: changed-files + uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6 with: - extra_args: --files ${{ env.CHANGED_FILES }} + safe_output: false # Output passed to environment variable to avoid command injection. + separator: '" "' # To account for paths with spaces, ensure our items are split by quotes internally. + skip_initial_fetch: true + files_yaml_from_source_file: .github/changed-files.yml - build: - runs-on: ${{matrix.os}} - name: ${{matrix.name}} - needs: static-checks - permissions: write-all + - name: Style checks via prek + uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2.0.4 + env: + CHANGED_FILES: '"${{ steps.changed-files.outputs.everything_all_changed_files }}"' # Wrap with quotes to bookend internal quote separators + with: + extra-args: --files ${{ env.CHANGED_FILES }} + + build-master: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + needs: static-checks-builds + if: needs.static-checks-builds.outputs.sources-changed == 'true' || github.event_name != 'pull_request' + permissions: + contents: read strategy: fail-fast: false matrix: @@ -59,126 +99,71 @@ jobs: target: template_debug platform: windows arch: x86_64 + test-bin-suffix: .md.exe + - identifier: windows-release os: windows-latest name: 🏁 Windows Release target: template_release platform: windows arch: x86_64 + test-bin-suffix: .md.exe + - identifier: macos-debug os: macos-latest name: 🍎 macOS (universal) Debug target: template_debug platform: macos arch: universal + - identifier: macos-release os: macos-latest name: 🍎 macOS (universal) Release target: template_release platform: macos arch: universal + - identifier: linux-debug - os: ubuntu-latest + os: ubuntu-22.04 name: 🐧 Linux Debug - runner: ubuntu-20.04 target: template_debug platform: linux arch: x86_64 + - identifier: linux-release - os: ubuntu-latest + os: ubuntu-22.04 name: 🐧 Linux Release - runner: ubuntu-20.04 target: template_release platform: linux arch: x86_64 steps: - name: Checkout project - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: submodules: recursive + persist-credentials: false - - name: Setup build cache - uses: OpenVicProject/openvic-cache@master + - name: Build + uses: ./.github/actions/openvic-sim-build with: - cache-name: ${{ matrix.identifier }} - base-branch: ${{ env.GH_BASE_BRANCH }} - continue-on-error: true - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.x" - - - name: Set up SCons - shell: bash - run: | - python -c "import sys; print(sys.version)" - python -m pip install scons - scons --version - - - name: Linux dependencies - if: ${{ matrix.platform == 'linux' }} - run: | - sudo apt-get update -qq - sudo apt-get install -qqq build-essential pkg-config libtbb-dev - g++ --version - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 12 - sudo update-alternatives --set g++ /usr/bin/g++-12 - g++ --version - - - name: Compile with SCons - uses: OpenVicProject/openvic-build@master - with: - platform: ${{ matrix.platform }} + identifier: ${{ matrix.identifier }} target: ${{ matrix.target }} - sconsflags: arch=${{ matrix.arch }} build_ovsim_library=yes run_ovsim_tests=yes build_ovsim_benchmarks=yes + platform: ${{ matrix.platform }} + arch: ${{ matrix.arch }} - - name: Delete compilation files - if: ${{ matrix.platform == 'windows' }} + - name: Run tests run: | - Remove-Item bin/* -Include *.exp,*.pdb -Force - - - name: Upload library artifact - uses: actions/upload-artifact@v4 - with: - name: ${{ github.event.repository.name }}-${{ matrix.identifier }}-library - path: | - ${{ github.workspace }}/bin/libopenvic-simulation.* - - - name: Upload executable artifact - uses: actions/upload-artifact@v4 - with: - name: ${{ github.event.repository.name }}-${{ matrix.identifier }}-executable - path: | - ${{ github.workspace }}/bin/openvic-simulation.headless.* - - - name: Archive Release - uses: thedoctor0/zip-release@0.7.6 - with: - type: "zip" - filename: "../../../libopenvic-simulation.${{ matrix.platform }}.${{ matrix.arch }}.zip" - directory: "${{ github.workspace }}/bin/" - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') - - - name: Create and upload asset - uses: ncipollo/release-action@v1.13.0 - with: - allowUpdates: true - artifacts: "libopenvic-simulation.${{ matrix.platform }}.${{ matrix.arch }}.zip" - omitNameDuringUpdate: true - omitBodyDuringUpdate: true - token: ${{ secrets.GITHUB_TOKEN }} - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') + ./tests/bin/openvic-simulation.tests.${{ matrix.platform }}.${{ matrix.target }}.${{ matrix.arch }}${{ matrix.test-bin-suffix || '' }} merge-library-files: - runs-on: ubuntu-latest - needs: build name: 📚 Merge Library Files + runs-on: ubuntu-latest + needs: build-master steps: - name: Merge Artifacts - uses: actions/upload-artifact/merge@v4 + uses: actions/upload-artifact/merge@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: delete-merged: true name: ${{ github.event.repository.name }}-library - pattern: ${{ github.event.repository.name }}-*-library + pattern: ${{ github.event.repository.name }}-*-library \ No newline at end of file diff --git a/.github/workflows/nightly-releases.yml b/.github/workflows/nightly-releases.yml new file mode 100644 index 000000000..c3587d96e --- /dev/null +++ b/.github/workflows/nightly-releases.yml @@ -0,0 +1,281 @@ +name: 🌘 Nightly Releases + +on: + schedule: + - cron: '23 0 * * *' + workflow_dispatch: + +permissions: {} + +env: + SHA_REGEX: ^[0-9a-fA-F]{40}$ + +jobs: + nightly-check: + name: Check for new commits + if: github.event_name == 'workflow_dispatch' || !vars.DISABLE_NIGHTLY_RELEASES + permissions: + contents: read + runs-on: ubuntu-latest + outputs: + commit: ${{ steps.check_for_new_commits.outputs.commit }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Validate repository variables + env: + VARS_VERSION_CORE: ${{ vars.NIGHTLY_VERSION_CORE }} + VARS_NIGHTLY_REPOSITORY: ${{ vars.NIGHTLY_REPOSITORY }} + SECRETS_NIGHTLY_REPOSITORY_TOKEN: ${{ secrets.NIGHTLY_REPOSITORY_TOKEN }} + VAR_DEFAULT_COMMIT_HASH: ${{ vars.DEFAULT_COMMIT_HASH }} + run: | + # Can report error for every validation check + EXIT_STATUS=0 + + validate_non_empty () { + [[ -n ${1-} ]] && return + echo "::error::${2-parameter} is empty." + EXIT_STATUS=1 + false + } + + if validate_non_empty "$VARS_VERSION_CORE" "vars.NIGHTLY_VERSION_CORE"; then + if [[ ! $VARS_VERSION_CORE =~ ^(0|[1-9][0-9]*)(\.(0|[1-9][0-9]*)){1,2}$ ]]; then + echo "::error::vars.NIGHTLY_VERSION_CORE should be set to 'MAJOR.MINOR', with an optional '.PATCH'." + EXIT_STATUS=1 + fi + fi + + if validate_non_empty "$VARS_NIGHTLY_REPOSITORY" "vars.NIGHTLY_REPOSITORY"; then + if [[ $VARS_NIGHTLY_REPOSITORY == */* ]]; then + echo "::error::vars.NIGHTLY_REPOSITORY cannot be set with a forward slash, that is an invalid repository name." + EXIT_STATUS=1 + fi + fi + + validate_non_empty "$SECRETS_NIGHTLY_REPOSITORY_TOKEN" "secrets.NIGHTLY_REPOSITORY_TOKEN" + + if validate_non_empty "$VAR_DEFAULT_COMMIT_HASH" "vars.DEFAULT_COMMIT_HASH"; then + if [[ ! $VAR_DEFAULT_COMMIT_HASH =~ $SHA_REGEX ]]; then + echo "::error::vars.DEFAULT_COMMIT_HASH is not set to a full Git commit SHA." + EXIT_STATUS=1 + fi + fi + + exit $EXIT_STATUS + + - name: Retrieve HEAD commit hash + id: head + shell: bash + run: echo "head=$(git rev-parse HEAD)" | tee -a "${GITHUB_OUTPUT}" + + - name: Cache nightly commit hash + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + env: + SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1 + with: + path: .nightly_commit_hash + key: release-nightly-${{ steps.head.outputs.head }} + restore-keys: | + release-nightly- + + - name: Check for new commits + id: check_for_new_commits + shell: bash + run: | + relevant_files=( + "deps/*" + "misc/*" + "scripts" + "src/*.hpp" + "src/*.cpp" + ':!src/openvic-simulation/pch.hpp' + ':!src/openvic-simulation/pch.cpp' + "pyproject.toml" + "SConstruct" + ".github/workflows/builds.yml" + ".github/actions/openvic-sim-release/action.yml" + ".github/workflows/nightly-releases.yml" + ".github/actions/openvic-sim-release/action.yml" + ".github/actions/openvic-sim-release/nightly-release-notes-configuration.json" + ) + if [[ -f .nightly_commit_hash ]]; then + limit_args=( + "$(cat .nightly_commit_hash)..HEAD" + ) + else + limit_args=( + --since="24 hours ago" + ) + fi + echo "commit=$(git log --format=%H -1 "${limit_args[@]}" -- "${relevant_files[@]}")" | tee -a "${GITHUB_OUTPUT}" + + - name: Record new nightly commit hash + env: + HEAD: ${{ steps.head.outputs.head }} + shell: bash + run: echo "${HEAD}" | tee .nightly_commit_hash + + nightly-build: + name: Build ${{ matrix.name }} + needs: nightly-check + if: needs.nightly-check.outputs.commit + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - identifier: windows-release + os: windows-latest + name: 🏁 Windows Release + target: template_release + platform: windows + arch: x86_64 + scons-flags: '' + + - identifier: macos-release + os: macos-latest + name: 🍎 macOS (universal) Release + target: template_release + platform: macos + arch: universal + scons-flags: 'lto=full' + + - identifier: linux-release + os: ubuntu-latest + name: 🐧 Linux Release + runner: ubuntu-22.04 + target: template_release + platform: linux + arch: x86_64 + scons-flags: 'lto=full use_static_cpp=yes' + + steps: + - name: Checkout project + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + submodules: recursive + persist-credentials: false + + - name: Build + uses: ./.github/actions/openvic-sim-build + with: + identifier: ${{ matrix.identifier }} + target: ${{ matrix.target }} + platform: ${{ matrix.platform }} + arch: ${{ matrix.arch }} + disable-cache: true + scons-flags: use_hot_reload=no build_ovsim_tests=no debug_symbols=yes optimize=speed_trace ${{ matrix.scons-flags }} + + publish-nightly-release: + name: Publish Release + runs-on: ubuntu-latest + needs: nightly-build + permissions: + contents: write # May be needed to publish release + env: + VARS_NIGHTLY_REPOSITORY: ${{ vars.NIGHTLY_REPOSITORY }} + steps: + - name: Shallow Clone + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 1 # See: https://github.blog/open-source/git/get-up-to-speed-with-partial-clone-and-shallow-clone/ + fetch-tags: true + persist-credentials: false + + - name: Retrieve master/nightly release tag info + env: + GH_TOKEN: ${{ github.token }} + run: | + echo "LAST_MASTER_TAG_INFO=$(gh release list -L 1 --json tagName,publishedAt --jq '.[0]')" >> $GITHUB_ENV + echo "LAST_NIGHTLY_TAG_INFO=$(gh release list -L 1 -R $GITHUB_REPOSITORY_OWNER/$VARS_NIGHTLY_REPOSITORY --json tagName,publishedAt --jq '.[0]')" >> $GITHUB_ENV + + - name: Query master/nightly release tag info for dates + run: | + echo "LAST_MASTER_TAG_PUB_DATE=$(jq -r ".publishedAt" <<< "$LAST_MASTER_TAG_INFO")" >> $GITHUB_ENV + echo "LAST_NIGHTLY_TAG_PUB_DATE=$(jq -r ".publishedAt" <<< "$LAST_NIGHTLY_TAG_INFO")" >> $GITHUB_ENV + + - name: Process master/nightly release tag dates + run: | + if [[ ! -z $LAST_NIGHTLY_TAG_PUB_DATE ]]; then + echo "LAST_MASTER_TAG_PUB_SEC=$(date -d $LAST_MASTER_TAG_PUB_DATE +%s)" >> $GITHUB_ENV + else + echo "LAST_MASTER_TAG_PUB_SEC=0" >> $GITHUB_ENV + fi + + if [[ ! -z $LAST_NIGHTLY_TAG_PUB_DATE ]]; then + echo "LAST_NIGHTLY_TAG_PUB_SEC=$(date -d $LAST_NIGHTLY_TAG_PUB_DATE +%s)" >> $GITHUB_ENV + else + echo "LAST_NIGHTLY_TAG_PUB_SEC=0" >> $GITHUB_ENV + fi + + - name: Use default values for LATEST_TAG, FROM_REF, and COMMIT_HASH + if: env.LAST_MASTER_TAG_PUB_SEC == 0 && env.LAST_MASTER_TAG_PUB_SEC == env.LAST_NIGHTLY_TAG_PUB_SEC + env: + VAR_DEFAULT_COMMIT_HASH: ${{ vars.DEFAULT_COMMIT_HASH }} + run: | + echo "LATEST_TAG=" >> $GITHUB_ENV + echo "COMMIT_HASH=$VAR_DEFAULT_COMMIT_HASH" >> $GITHUB_ENV + echo "FROM_REF=$VAR_DEFAULT_COMMIT_HASH" >> $GITHUB_ENV + + - name: Get FROM_REF, LATEST_TAG, and COMMIT_HASH from latest master release + if: env.LAST_MASTER_TAG_PUB_SEC > env.LAST_NIGHTLY_TAG_PUB_SEC + run: | + LATEST_TAG=$(jq -r '.tagName' <<< "$LAST_MASTER_TAG_INFO") + echo "::debug::LATEST_TAG=$LATEST_TAG" + + COMMIT_HASH=$(git rev-parse --verify -q $LATEST_TAG) + echo "::debug::COMMIT_HASH=$COMMIT_HASH" + + echo "LATEST_TAG=$LATEST_TAG" >> $GITHUB_ENV + echo "COMMIT_HASH=$COMMIT_HASH" >> $GITHUB_ENV + echo "FROM_REF=$LATEST_TAG" >> $GITHUB_ENV + + - name: Get FROM_REF, LATEST_TAG, and COMMIT_HASH from latest nightly release + if: env.LAST_MASTER_TAG_PUB_SEC < env.LAST_NIGHTLY_TAG_PUB_SEC + env: + GH_TOKEN: ${{ github.token }} + run: | + LATEST_TAG=$(jq -r '.tagName' <<< "$LAST_NIGHTLY_TAG_INFO") + echo "::debug::LATEST_TAG=$LATEST_TAG" + + LATEST_RELEASE_BODY=$(gh release view $LATEST_TAG -R $GITHUB_REPOSITORY_OWNER/$VARS_NIGHTLY_REPOSITORY --json body --jq '.body') + echo "::debug::LATEST_RELEASE_BODY=$LATEST_RELEASE_BODY" + + # Keep up to date with .github/actions/openvic-sim-release/nightly-release-notes-configuration.json + HASH_OF_TAG=$(grep -oP "Generated from: $GITHUB_REPOSITORY@\K[a-zA-Z0-9]+" <<< "$LATEST_RELEASE_BODY") + echo "::debug::HASH_OF_TAG=$HASH_OF_TAG" + + COMMIT_HASH=$(git rev-parse --verify -q $HASH_OF_TAG) + echo "::debug::COMMIT_HASH=$COMMIT_HASH" + + if [[ -z $COMMIT_HASH ]]; then + echo "::error::Could not find commit for hash $HASH_OF_TAG." + exit 1 + fi + + echo "LATEST_TAG=$LATEST_TAG" >> $GITHUB_ENV + echo "COMMIT_HASH=$COMMIT_HASH" >> $GITHUB_ENV + echo "FROM_REF=$COMMIT_HASH" >> $GITHUB_ENV + + - name: Generate TAG_NAME from vars.NIGHTLY_VERSION_CORE + env: + VARS_VERSION_CORE: ${{ vars.NIGHTLY_VERSION_CORE }} + run: echo "TAG_NAME=v$VARS_VERSION_CORE-nightly.$(date +%Y.%m.%d)+$GITHUB_SHA" >> $GITHUB_ENV + + - name: Publish Nightly Release + uses: ./.github/actions/openvic-sim-release + with: + latest: ${{ github.ref_name == 'master' }} + nightly-release: true + tag-name: ${{ env.TAG_NAME }} + from-ref: ${{ env.FROM_REF }} + from-tag: ${{ env.LATEST_TAG }} + to-ref: ${{ github.sha }} + target-repo: ${{ vars.NIGHTLY_REPOSITORY }} + src-token: ${{ secrets.GITHUB_TOKEN }} + target-token: ${{ secrets.NIGHTLY_REPOSITORY_TOKEN }} + diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml new file mode 100644 index 000000000..4cf551cd5 --- /dev/null +++ b/.github/workflows/releases.yml @@ -0,0 +1,138 @@ +name: 🚀 Releases + +on: + push: + tags: ["v*"] + +permissions: {} + +env: + SEMVER_REGEX: ^v(0|[1-9][0-9]*)((\.(0|[1-9][0-9]*)){1,2})(-(alpha|beta|rc)\.([1-9][0-9]*))?$ + SEMVER_SNAPSHOT_REGEX: ^v(0|[1-9][0-9]*)((\.(0|[1-9][0-9]*)){1,2})-(snapshot|snapshot\.dev)\.([1-9][0-9]*)\+([0-9a-fA-F]{40})$ + +jobs: + static-checks-release: + name: Code style, file formatting, and docs + if: vars.DISABLE_TAG_RELEASES != true + runs-on: ubuntu-latest + steps: + - name: Checkout project + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 # Treeless clone. Slightly less performant than a shallow clone, but makes finding diffs instantaneous. + filter: tree:0 # See: https://github.blog/open-source/git/get-up-to-speed-with-partial-clone-and-shallow-clone/ + persist-credentials: false + + - name: Validate tag + env: + GITHUB_REF_NAME: ${{ github.ref_name }} + run: | + validate_version () { + [[ $1 =~ $SEMVER_REGEX ]] && return + [[ $1 =~ $SEMVER_SNAPSHOT_REGEX ]] && return + + echo "::error::${2:-parameter} is not a valid semver string for versioning starting with v. Valid prerelease values are 'alpha', 'beta', 'rc', 'snapshot', and 'snapshot.dev'. A count value must follow all prerelease tags, starting from 1. 'snapshot' and 'snapshot.dev' must include the full commit SHA as a build string" + false + } + + if ! validate_version "$GITHUB_REF_NAME" "github.ref (tag)"; then + exit 1 + fi + + - name: Install APT dependencies + uses: awalsh128/cache-apt-pkgs-action@acb598e5ddbc6f68a970c5da0688d2f3a9f04d05 # v1.6.0 + with: + packages: libxml2-utils + + - name: Style checks via prek + uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2.0.4 + + build-release: + name: ${{ matrix.name }} Release + needs: static-checks-release + runs-on: ${{ matrix.os }} + permissions: + contents: read + strategy: + fail-fast: false + matrix: + include: + - identifier: windows-release + os: windows-latest + name: 🏁 Build Windows + target: template_release + platform: windows + arch: x86_64 + scons-flags: '' + + - identifier: macos-release + os: macos-latest + name: 🍎 Build macOS + target: template_release + platform: macos + arch: universal + scons-flags: lto=full + + - identifier: linux-release + os: ubuntu-latest + name: 🐧 Build Linux + runner: ubuntu-22.04 + target: template_release + platform: linux + arch: x86_64 + scons-flags: lto=full use_static_cpp=yes + + steps: + - name: Checkout project + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + submodules: recursive + persist-credentials: false + + - name: Build + uses: ./.github/actions/openvic-sim-build + with: + identifier: ${{ matrix.identifier }} + target: ${{ matrix.target }} + platform: ${{ matrix.platform }} + arch: ${{ matrix.arch }} + disable-cache: true + scons-flags: use_hot_reload=no build_ovsim_tests=no ${{ matrix.scons-flags }} + + publish-release: + name: Publish Release + runs-on: ubuntu-latest + needs: build-release + permissions: + contents: write # May be needed to publish release + env: + IS_PRERELEASE: ${{ + contains(github.ref, '-alpha') || + contains(github.ref, '-beta') || + contains(github.ref, '-rc') || + contains(github.ref, '-snapshot') + }} + IS_SNAPSHOT: ${{ contains(github.ref, '-snapshot') }} + steps: + - name: Shallow Clone + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 1 # See: https://github.blog/open-source/git/get-up-to-speed-with-partial-clone-and-shallow-clone/ + persist-credentials: false + + - name: Get FROM_REF + env: + GH_TOKEN: ${{ github.token }} + EXCLUDE_PRE_RELEASES: ${{ !env.IS_PRERELEASE && '--exclude-pre-releases' || '' }} + EXCLUDE_SNAPSHOTS: ${{ !env.IS_SNAPSHOT && '| select(.tagName | contains("-snapshot") | not)' || '' }} + run: + echo "FROM_REF=$(gh release list $EXCLUDE_PRE_RELEASES --json tagName --jq "[.[] $EXCLUDE_SNAPSHOTS.tagName][0]")" >> $GITHUB_ENV + + - name: Publish Release + uses: ./.github/actions/openvic-sim-release + with: + latest: ${{ !env.IS_PRERELEASE && !env.IS_SNAPSHOT }} + prerelease: ${{ env.IS_PRERELEASE }} + snapshot-release: ${{ env.IS_SNAPSHOT }} + from-ref: ${{ env.FROM_REF || vars.DEFAULT_COMMIT_HASH }} + src-token: ${{ secrets.GITHUB_TOKEN }}