From 41da3bd5f53c566c93f70aa65c58bf5be72885f9 Mon Sep 17 00:00:00 2001 From: Logan Drescher Date: Sun, 22 Sep 2024 00:42:03 -0400 Subject: [PATCH] Overhauled CI/CD, now uses poetry --- .github/workflows/ci.yml | 190 ++++++++++++++++----------------------- biosimulators.json | 6 +- 2 files changed, 82 insertions(+), 114 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 244acb9..db4cc9a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,16 +18,12 @@ jobs: name: Update simulator version, lint, test, compile documentation, and release runs-on: ubuntu-latest outputs: - mainBranch: ${{ steps.get-main-branch.outputs.mainBranch }} - mainBranchRef: ${{ steps.get-main-branch.outputs.mainBranchRef }} - mainBranchHeadRevision: ${{ steps.get-main-branch.outputs.mainBranchHeadRevision }} - version: ${{ steps.get-version-number.outputs.version }} + version: ${{ steps.get-tagged-version.outputs.version }} simulatorId: ${{ steps.get-docker-image-tag.outputs.simulatorId }} simulatorVersion: ${{ steps.get-docker-image-tag.outputs.simulatorVersion }} simulatorName: ${{ steps.get-docker-image-tag.outputs.simulatorName }} dockerImageBaseUrl: ${{ steps.get-docker-image-tag.outputs.dockerImageBaseUrl }} dockerRegistry: ${{ steps.get-docker-image-tag.outputs.dockerRegistry }} - release: ${{ steps.determine-if-release-needed.outputs.release }} docsChanged: ${{ steps.commit-docs.outputs.docsChanged }} defaults: run: @@ -38,6 +34,18 @@ jobs: with: fetch-depth: 1 + ############################################# + ## If tagged, set the `_version.py` file to reflect it + ############################################# + - name: Align Version with tag + id: get-tagged-version + if: startsWith(github.ref, 'refs/tags/') + run: | + taggedVersion = $(echo $(echo "refs/tags/22.2" | cut -d '/' -f 3)) + echo "processing `$taggedVersion`" + echo "__version__ = ${taggedVersion}" > biosimulators_copasi/_version.py + echo "version=${taggedVersion}" >> $GITHUB_OUTPUT + ############################################# ## Install package and its dependencies ############################################# @@ -48,85 +56,83 @@ jobs: python-version: "3.10" ############################################# - ## Update the version of the simulator + ## Lint and Test ############################################# + - name: Lint the package + run: poetry run python -m flake8 + + - name: Run the tests + run: poetry run python -m pytest tests/ --cov=./biosimulators_copasi/ --cov-report=xml + + - name: Upload the coverage report to Codecov + uses: codecov/codecov-action@v2 + with: + token: ${{ secrets.CODECOV_TOKEN }} + flags: unittests + file: ./coverage.xml + + ############################################# + ## Compile documentation + ############################################# + - name: Install the requirements for compiling the documentation + run: poetry install --with docs + + - name: Compile the documentation + run: | + poetry run sphinx-apidoc . pyproject.toml --output-dir docs-src/source --force --module-first --no-toc + mkdir -p docs-src/_static + poetry run sphinx-build docs-src docs + + ############################################# + ## Apply the version of the simulator to `biosimulators.json` + ############################################# + - name: Gets latest created release info + id: latest_release_info + uses: jossef/action-latest-release-info@v1.2.2 + - id: update-simulator-version name: Update the version of the simulator - if: github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' run: | - if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then - simulatorVersion="${{ github.event.inputs.simulatorVersion }}" - else - simulatorVersion=$(poetry -q run python -c "import COPASI; print(COPASI.__version__)") - fi + # We version the containers with the `biosimulators_copasi` version, but list the version as the + # COPASI version inside. + copasiVersion = $(poetry -q run python -c "import COPASI; print(COPASI.__version__)") + bioSimVersion = $(poetry -q run python -c "import biosimulators_copasi as bsc; print(bsc.__version__)") + oldBioSimVersion = ${{ steps.latest_release_info.outputs.tag_name }} - simulatorSpecVersion=$(jq -r '.version' biosimulators.json) - set +e - dpkg --compare-versions "$simulatorVersion" ge "$simulatorSpecVersion" - if [[ $? = 0 ]]; then - simulatorVersionLatest="true" - else - simulatorVersionLatest="false" - fi - dpkg --compare-versions "$simulatorVersion" gt "$simulatorSpecVersion" - if [[ $? = 0 ]]; then - simulatorVersionNewer="true" + if [ $oldBioSimVersion < $bioSimVersion]; then + echo "needDeploy=true" >> "$GITHUB_OUTPUT" else - simulatorVersionNewer="false" + echo "needDeploy=false" >> "$GITHUB_OUTPUT" fi - set -e - sudo apt-get update -y - sudo apt-get install -y --no-install-recommends jq moreutils + sed -i -e 's/__COPASI_VERSION__/${copasiVersion}/g' biosimulators.json - IMAGE_BASE_URL=$(jq -r '.image.url' biosimulators.json | cut -d : -f 1) - jq ".version = \"${simulatorVersion}\"" biosimulators.json | sponge biosimulators.json - jq ".image.url = \"${IMAGE_BASE_URL}:${simulatorVersion}\"" biosimulators.json | sponge biosimulators.json + sed -i -E \ + "s/ARG SIMULATOR_VERSION=([^ \n]+|\".*?\")/ARG SIMULATOR_VERSION=\"${copasiVersion}\"/" \ + Dockerfile sed -i -E \ - "s/SIMULATOR_VERSION=([^ \n]+|\".*?\")/SIMULATOR_VERSION=\"${simulatorVersion}\"/" \ + "s/ARG VERSION=([^ \n]+|\".*?\")/ARG VERSION=\"${bioSimVersion}\"/" \ Dockerfile - echo "::set-output name=simulatorVersion::$simulatorVersion" - echo "::set-output name=simulatorVersionLatest::$simulatorVersionLatest" - echo "::set-output name=simulatorVersionNewer::$simulatorVersionNewer" + echo "::set-output name=biosimulatorsVersion::$bioSimVersion" + echo "::set-output name=simulatorVersion::$copasiVersion" + echo + ############################################# + ## Check for Deploy, Stop if not Deploying + ############################################# - name: Cancel build if the specifications already have the latest version of COPASI uses: andymckay/cancel-action@0.2 - if: github.event_name == 'schedule' && steps.update-simulator-version.outputs.simulatorVersionNewer != 'true' + if: github.event_name == 'schedule' && steps.update-simulator-version.outputs.needDeploy != 'true' ############################################# - ## Lint and Test + ## Release ############################################# - - name: Lint the package - run: poetry run python -m flake8 - - - name: Run the tests - run: poetry run python -m pytest tests/ --cov=./biosimulators_copasi/ --cov-report=xml - - - name: Upload the coverage report to Codecov - uses: codecov/codecov-action@v2 - with: - token: ${{ secrets.CODECOV_TOKEN }} - flags: unittests - file: ./coverage.xml ############################################# ## Build Docker image ############################################# - - id: get-version-number - name: Get version number - env: - TAG: ${{ github.ref }} - run: | - if [[ "${TAG}" =~ ^refs/tags/ ]]; then - version="${TAG/refs\/tags\//}" - else - version=$(poetry run python -c "import glob; import importlib.util; version_filename = glob.glob('**/_version.py', recursive=True)[0]; spec = importlib.util.spec_from_file_location('module.name', version_filename); module = importlib.util.module_from_spec(spec); spec.loader.exec_module(module); print(module.__version__)") - fi - - echo "::set-output name=version::$version" - - id: get-docker-image-tag name: Determine Docker image tag run: | @@ -153,24 +159,23 @@ jobs: --label org.opencontainers.image.source=https://github.com/${{ github.repository }} \ --label org.opencontainers.image.revision=${REVISION} \ --label org.opencontainers.image.created=${CREATED} \ - --build-arg VERSION=${{ steps.get-version-number.outputs.version }} \ + --build-arg VERSION=${{ steps.get-tagged-version.outputs.version }} \ --build-arg SIMULATOR_VERSION=${{ steps.get-docker-image-tag.outputs.simulatorVersion }} \ --tag ${{ steps.get-docker-image-tag.outputs.dockerImageBaseUrl }}:${{ steps.get-docker-image-tag.outputs.simulatorVersion }} \ --tag ${{ steps.get-docker-image-tag.outputs.dockerImageBaseUrl }}:latest \ . - ############################################# - ## Compile documentation + ## Apply the digest of the container to `biosimulators.json` ############################################# - - name: Install the requirements for compiling the documentation - run: poetry install --with docs - - - name: Compile the documentation + - name: Update the version of the simulator run: | - poetry run sphinx-apidoc . pyproject.toml --output-dir docs-src/source --force --module-first --no-toc - mkdir -p docs-src/_static - poetry run sphinx-build docs-src docs + containerLabel=${{ steps.get-docker-image-tag.outputs.dockerImageBaseUrl }}:${{ steps.get-docker-image-tag.outputs.simulatorVersion }} + docker pull $containerLabel + imageId=docker image ls | grep ${{ steps.get-docker-image-tag.outputs.dockerImageBaseUrl }} \ + grep ${{ steps.get-docker-image-tag.outputs.simulatorVersion }} | awk '{ print $3; ]' + dockerDigest=docker inspect --format='{{index .RepoDigests 0}}' $imageId | cut -d '@' -f 2 + sed -i -e 's/__CONTAINER_DIGEST__/${dockerDigest}/g' biosimulators.json ############################################# ## Commit and push new version of simulator @@ -197,42 +202,9 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} branch: ${{ github.ref }} - ############################################# - ## Release - ############################################# - - - id: determine-if-release-needed - name: Determine if a release should be made - run: | - release="0" - - echo "Simulator Version: `${{ github.event.inputs.simulatorVersion }}`" - echo "Input Version: `${{ steps.update-simulator-version.outputs.simulatorVersion }}`" - echo "Simulator Version: `${{ github.event.inputs.simulatorVersion }}`"3 - - if [ "true" == "${{ github.event.inputs.simulatorVersion }}" ]; then - release="1" - fi - - if [ ! -z "${{ steps.update-simulator-version.outputs.simulatorVersion }}" ]; then - if [ "${{ github.ref }}" == "dev" ]; then - release="1" - fi - fi - - if [[ "${{ github.ref }}" =~ ^refs/tags/ ]]; then - tag_hash=$(git rev-parse "${{ github.ref }}") - if [ "$tag_hash" == "${{ steps.get-main-branch.outputs.mainBranchHeadRevision }}" ]; then - release="1" - fi - fi - - echo "::set-output name=release::$release" - # If new tag, commit and push documentation - id: commit-docs name: Commit the compiled documentation - if: startsWith(github.ref, 'refs/tags/') && steps.determine-if-release-needed.outputs.release == '1' run: | git config --local user.email "biosimulators.daemon@gmail.com" git config --local user.name "biosimulatorsdaemon" @@ -254,7 +226,7 @@ jobs: echo "::set-output name=docsChanged::$docsChanged" - name: Push the compiled documentation - if: startsWith(github.ref, 'refs/tags/') && steps.determine-if-release-needed.outputs.release == '1' && steps.commit-docs.outputs.docsChanged == '1' + if: steps.commit-docs.outputs.docsChanged == '1' uses: ad-m/github-push-action@master with: github_token: ${{ secrets.GITHUB_TOKEN }} @@ -262,17 +234,15 @@ jobs: # Create GitHub release - name: Create GitHub release - if: startsWith(github.ref, 'refs/tags/') && steps.determine-if-release-needed.outputs.release == '1' uses: actions/create-release@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tag_name: ${{ steps.get-version-number.outputs.version }} - release_name: Release ${{ steps.get-version-number.outputs.version }} + tag_name: ${{ steps.get-tagged-version.outputs.version }} + release_name: Release ${{ steps.get-tagged-version.outputs.version }} # Create PyPI release - name: Create PyPI release - if: startsWith(github.ref, 'refs/tags/') && steps.determine-if-release-needed.outputs.release == '1' env: POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }} run: | @@ -295,7 +265,6 @@ jobs: poetry publish --no-interaction --username __token__ --password $POETRY_PYPI_TOKEN_PYPI # build Docker image and push to GitHub Container Registry - name: Push Docker image - if: steps.determine-if-release-needed.outputs.release == '1' run: | docker login ${{ steps.get-docker-image-tag.outputs.dockerRegistry }} \ --username ${{ secrets.DOCKER_REGISTRY_USERNAME }} \ @@ -308,7 +277,6 @@ jobs: # Submit to BioSimulators registry - name: Submit to BioSimulators registry - if: steps.determine-if-release-needed.outputs.release == '1' run: | REVISION=$(git rev-parse HEAD) IMAGE_DIGEST=$(docker image inspect ${{ steps.get-docker-image-tag.outputs.dockerImageBaseUrl }}:${{ steps.get-docker-image-tag.outputs.simulatorVersion }} | jq -r '.[0].RepoDigests[0]' | cut -d "@" -f 2-) diff --git a/biosimulators.json b/biosimulators.json index 5c93582..ec0178e 100644 --- a/biosimulators.json +++ b/biosimulators.json @@ -1,7 +1,7 @@ { "id": "copasi", "name": "COPASI", - "version": "4.44.295", + "version": "__COPASI_VERSION__", "description": "COPASI is a C++-based software application for the simulation and analysis of biochemical networks and their dynamics.", "urls": [ { @@ -10,8 +10,8 @@ } ], "image": { - "url": "ghcr.io/biosimulators/biosimulators_copasi/copasi:4.44.295", - "digest": "sha256:d32d7a427b8aeec14acab3ade77f01223082c65d1978d3a150ba863eca8d5b64", + "url": "ghcr.io/biosimulators/biosimulators_copasi/basico:__COPASI_VERSION__", + "digest": "__CONTAINER_DIGEST__", "format": { "namespace": "EDAM", "id": "format_3973",