diff --git a/.github/workflows/docker-openstudio.yml b/.github/workflows/docker-openstudio.yml index d0adb14..48b40c6 100644 --- a/.github/workflows/docker-openstudio.yml +++ b/.github/workflows/docker-openstudio.yml @@ -8,89 +8,96 @@ on: [push, pull_request] # branches: # - test_branch +concurrency: + group: openstudio-docker-${{ github.ref }} + cancel-in-progress: true + env: USE_TESTING_TIMEOUTS: "true" - OPENSTUDIO_VERSION: 3.10.0 - OPENSTUDIO_SHA: 2B83cec57525 + OPENSTUDIO_VERSION: 3.11.0 + OPENSTUDIO_SHA: c7f13ad615 OPENSTUDIO_VERSION_EXT: "-alpha" + OPENSTUDIO_DOWNLOAD_URL: "https://openstudio-ci-builds.s3-us-west-2.amazonaws.com/develop/OpenStudio-3.11.0-alpha%2Bc7f13ad615-Ubuntu-22.04-x86_64.deb" permissions: contents: read - id-token: write jobs: docker: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 - with: - python-version: '3.8.x' + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.11.x' - - name: test and build - shell: bash - run: | + - name: test and build + shell: bash + run: | + set -euo pipefail docker build -t openstudio:latest \ - --build-arg OPENSTUDIO_VERSION=$OPENSTUDIO_VERSION \ - --build-arg OPENSTUDIO_SHA=$OPENSTUDIO_SHA \ - --build-arg OPENSTUDIO_VERSION_EXT=$OPENSTUDIO_VERSION_EXT \ - --build-arg DOWNLOAD_PREFIX=$DOWNLOAD_PREFIX . + --build-arg OPENSTUDIO_VERSION=$OPENSTUDIO_VERSION \ + --build-arg OPENSTUDIO_SHA=$OPENSTUDIO_SHA \ + --build-arg OPENSTUDIO_VERSION_EXT=$OPENSTUDIO_VERSION_EXT . docker run openstudio:latest openstudio openstudio_version docker run openstudio:latest /usr/local/openstudio-$OPENSTUDIO_VERSION/Radiance/bin/rtrace -version - docker run -v $(pwd):/var/simdata/openstudio openstudio:latest ruby /var/simdata/openstudio/test/test_run.rb - docker run -v $(pwd)/test:/var/simdata/openstudio openstudio:latest ./test_gemfile.sh + docker run -v "$(pwd)":/var/simdata/openstudio openstudio:latest ruby /var/simdata/openstudio/test/test_run.rb + docker run -v "$(pwd)/test":/var/simdata/openstudio openstudio:latest ./test_gemfile.sh - - name: deploy docker - if: ${{ success() }} && - github.ref == 'refs/heads/master' || - github.ref == 'refs/heads/develop' || - github.ref == 'refs/heads/custom_branch_name' - shell: bash - run: ./deploy_docker.sh - env: - DOCKER_PASS: ${{ secrets.DOCKER_PASS }} - DOCKER_USER: ${{ secrets.DOCKER_USER }} + - name: deploy docker + if: ${{ success() && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/custom_branch_name') }} + shell: bash + run: | + set -euo pipefail + ./deploy_docker.sh + env: + DOCKER_PASS: ${{ secrets.DOCKER_PASS }} + DOCKER_USER: ${{ secrets.DOCKER_USER }} apptainer: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 - with: - python-version: '3.8.x' + runs-on: ubuntu-24.04 + needs: docker + if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/custom_branch_name' }} + permissions: + contents: read + id-token: write + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.11.x' + + - name: install apptainer + shell: bash + run: | + set -euo pipefail + sudo add-apt-repository -y ppa:apptainer/ppa + sudo apt update + sudo apt install -y apptainer + + - name: build apptainer + shell: bash + run: | + set -euo pipefail + apptainer build \ + OpenStudio-$OPENSTUDIO_VERSION$OPENSTUDIO_VERSION_EXT.$OPENSTUDIO_SHA-Apptainer.sif \ + docker://nrel/openstudio:$OPENSTUDIO_VERSION$OPENSTUDIO_VERSION_EXT - - name: install apptainer - shell: bash - run: | - sudo add-apt-repository -y ppa:apptainer/ppa - sudo apt update - sudo apt install -y apptainer + - uses: actions/upload-artifact@v4 + with: + name: apptainer-image + path: OpenStudio-${{ env.OPENSTUDIO_VERSION }}${{ env.OPENSTUDIO_VERSION_EXT }}.${{ env.OPENSTUDIO_SHA }}-Apptainer.sif - - name: build apptainer - shell: bash - run: | - apptainer build \ - OpenStudio-$OPENSTUDIO_VERSION$OPENSTUDIO_VERSION_EXT.$OPENSTUDIO_SHA-Apptainer.sif \ - docker://nrel/openstudio:develop - #docker://nrel/openstudio:$OPENSTUDIO_VERSION$OPENSTUDIO_VERSION_EXT - - - - uses: actions/upload-artifact@v4 - with: - name: apptainer-image - path: OpenStudio-${{ env.OPENSTUDIO_VERSION }}${{ env.OPENSTUDIO_VERSION_EXT }}.${{ env.OPENSTUDIO_SHA }}-Apptainer.sif - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v3 - with: - aws-region: ${{ secrets.AWS_DEFAULT_REGION }} - role-to-assume: arn:aws:iam::471211731895:role/OpenStudioGitHubActionsRole - role-session-name: GitHubActions + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v3 + with: + aws-region: ${{ secrets.AWS_DEFAULT_REGION }} + role-to-assume: arn:aws:iam::471211731895:role/OpenStudioGitHubActionsRole + role-session-name: GitHubActions - - name: Upload artifacts to AWS S3 - uses: usualdesigner/s3-artifact-upload@main - with: - bucket-name: openstudio-builds - prefix: ${{env.OPENSTUDIO_VERSION}} - file: OpenStudio-${{ env.OPENSTUDIO_VERSION }}${{ env.OPENSTUDIO_VERSION_EXT }}.${{ env.OPENSTUDIO_SHA }}-Apptainer.sif - + - name: Upload artifacts to AWS S3 + uses: usualdesigner/s3-artifact-upload@main + with: + bucket-name: openstudio-builds + prefix: ${{ env.OPENSTUDIO_VERSION }} + file: OpenStudio-${{ env.OPENSTUDIO_VERSION }}${{ env.OPENSTUDIO_VERSION_EXT }}.${{ env.OPENSTUDIO_SHA }}-Apptainer.sif diff --git a/.github/workflows/manual_installer_test.yml b/.github/workflows/manual_installer_test.yml index 948b7dd..459a093 100644 --- a/.github/workflows/manual_installer_test.yml +++ b/.github/workflows/manual_installer_test.yml @@ -28,10 +28,10 @@ jobs: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: - python-version: '3.8.x' + python-version: '3.11.x' - name: test and build shell: bash diff --git a/Dockerfile b/Dockerfile index f35d40f..48353dc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,10 @@ MAINTAINER Nicholas Long nicholas.long@nrel.gov # Set the version of OpenStudio when building the container. For example `docker build --build-arg ARG OPENSTUDIO_VERSION=3.10.0 ARG OPENSTUDIO_VERSION_EXT="-alpha" -ARG OPENSTUDIO_DOWNLOAD_URL="https://openstudio-ci-builds.s3.amazonaws.com/develop/OpenStudio-3.10.0-alpha%2B83cec57525-Ubuntu-22.04-x86_64.deb" +ARG OPENSTUDIO_SHA="" +# If OPENSTUDIO_DOWNLOAD_URL is not provided, construct a reasonable default using the +# OpenStudio CI S3 pattern. Users can override by passing --build-arg OPENSTUDIO_DOWNLOAD_URL=... +ARG OPENSTUDIO_DOWNLOAD_URL="" ENV RC_RELEASE=TRUE ENV OS_BUNDLER_VERSION=2.4.10 ENV RUBY_VERSION=3.2.2 @@ -17,19 +20,27 @@ ENV BUNDLE_WITHOUT=native_ext # install locales and set to en_US.UTF-8. This is needed for running the CLI on some machines # such as singularity. RUN apt-get update && apt-get install -y \ - curl \ - gdebi-core \ - libsqlite3-dev \ - libssl-dev \ - libffi-dev \ - build-essential \ - zlib1g-dev \ - vim \ - git \ - locales \ - sudo \ - && echo "OpenStudio Package Download URL is ${OPENSTUDIO_DOWNLOAD_URL}" \ - && curl -SLO $OPENSTUDIO_DOWNLOAD_URL \ + curl \ + gdebi-core \ + libsqlite3-dev \ + libssl-dev \ + libffi-dev \ + build-essential \ + zlib1g-dev \ + vim \ + git \ + locales \ + sudo \ + && if [ -z "${OPENSTUDIO_DOWNLOAD_URL}" ]; then \ + ESC_VERSION=$(echo "${OPENSTUDIO_VERSION}${OPENSTUDIO_VERSION_EXT}" | sed 's/+/%2B/g'); \ + if [ -n "${OPENSTUDIO_SHA}" ]; then \ + OPENSTUDIO_DOWNLOAD_URL="https://openstudio-ci-builds.s3.amazonaws.com/develop/OpenStudio-${ESC_VERSION}%2B${OPENSTUDIO_SHA}-Ubuntu-22.04-x86_64.deb"; \ + else \ + OPENSTUDIO_DOWNLOAD_URL="https://openstudio-ci-builds.s3.amazonaws.com/develop/OpenStudio-${ESC_VERSION}-Ubuntu-22.04-x86_64.deb"; \ + fi; \ + fi \ + && echo "OpenStudio Package Download URL is ${OPENSTUDIO_DOWNLOAD_URL}" \ + && curl -SLO "$OPENSTUDIO_DOWNLOAD_URL" \ && OPENSTUDIO_DOWNLOAD_FILENAME=$(ls *.deb) \ # Verify that the download was successful (not access denied XML from s3) && grep -v -q "AccessDenied" ${OPENSTUDIO_DOWNLOAD_FILENAME} \ @@ -49,27 +60,29 @@ RUN curl -SLO -k https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.2.tar.gz \ && ./configure \ && make && make install -## if the openstudio-${OPENSTUDIO_VERSION} folder existed, set it as the OPENSTUDIO -## folder, otherwise set the openstudio-${OPENSTUDIO_VERSION}${OPENSTUDIO_VERSION_EXT} folder +## Detect the OpenStudio installation folder +## The folder will be openstudio-3.9.0 or something like openstudio-3.9.0-alpha +## We search for any folder matching the version pattern to handle various naming conventions -#the folder will be Openstudio-3.9.0 or something like Openstudio-3.9.0-alpha - -RUN if [ -d "/usr/local/openstudio-${OPENSTUDIO_VERSION}" ]; then \ - echo "OpenStudio folder is /usr/local/openstudio-${OPENSTUDIO_VERSION}"; \ - OPENSTUDIO_FOLDER=/usr/local/openstudio-${OPENSTUDIO_VERSION}; \ - else \ - echo "OpenStudio folder is /usr/local/openstudio-${OPENSTUDIO_VERSION}${OPENSTUDIO_VERSION_EXT}"; \ - OPENSTUDIO_FOLDER=/usr/local/openstudio-${OPENSTUDIO_VERSION}${OPENSTUDIO_VERSION_EXT}; \ +RUN echo "Searching for OpenStudio installation..." \ + && ls -la /usr/local \ + && ls -la /usr \ + && OPENSTUDIO_FOLDER=$(find /usr -maxdepth 2 -type d -name "openstudio-${OPENSTUDIO_VERSION}*" 2>/dev/null | head -1) \ + && if [ -z "$OPENSTUDIO_FOLDER" ]; then \ + echo "ERROR: OpenStudio folder not found matching pattern openstudio-${OPENSTUDIO_VERSION}*"; \ + echo "Searching for any openstudio folder..."; \ + find /usr -maxdepth 2 -type d -name "openstudio-*" 2>/dev/null; \ + exit 1; \ fi \ && echo "OpenStudio folder is ${OPENSTUDIO_FOLDER}" \ + && ls -la ${OPENSTUDIO_FOLDER} \ && rm -rf ruby* \ && gem install bundler -v $OS_BUNDLER_VERSION \ && gem install zip \ && mkdir /var/oscli \ - && ls /usr/local \ && cp ${OPENSTUDIO_FOLDER}/Ruby/Gemfile /var/oscli/ \ && cp ${OPENSTUDIO_FOLDER}/Ruby/Gemfile.lock /var/oscli/ \ - && cp ${OPENSTUDIO_FOLDER}/Ruby/openstudio-gems.gemspec /var/oscli/\ + && cp ${OPENSTUDIO_FOLDER}/Ruby/openstudio-gems.gemspec /var/oscli/ \ && ln -s ${OPENSTUDIO_FOLDER} /usr/local/openstudio-${OPENSTUDIO_VERSION} ENV RUBYLIB=/usr/local/openstudio-${OPENSTUDIO_VERSION}/Ruby diff --git a/README.md b/README.md index c22be36..300ae1a 100644 --- a/README.md +++ b/README.md @@ -85,3 +85,31 @@ If gem dependencies are required as part of the CLI outside of those # Issues Please submit issues on the project's [Github](https://github.com/nrel/docker-openstudio) page. + +## Building and publishing specific OpenStudio versions + + - **Local build for a specific version (example: 3.11.0-alpha):** + +```bash +docker build -t openstudio:latest \ + --build-arg OPENSTUDIO_VERSION=3.11.0 \ + --build-arg OPENSTUDIO_VERSION_EXT="-alpha" \ + --build-arg OPENSTUDIO_SHA= . +``` + +- **Tag and push locally (optional):** + +```bash +docker tag openstudio:latest yourrepo/openstudio:3.11.0-alpha +docker push yourrepo/openstudio:3.11.0-alpha +``` + +- **Trigger GitHub Actions build to publish to Docker Hub:** + + - Update `.github/workflows/docker-openstudio.yml` env values for `OPENSTUDIO_VERSION`, `OPENSTUDIO_VERSION_EXT`, and `OPENSTUDIO_SHA` on a branch. + - Create a pull request to `develop` and merge; the workflow will build and, if on `develop`, push the image to Docker Hub as the `develop` tag (and `latest`). + +Notes: + +- The `deploy_docker.sh` script tags images pushed to Docker Hub. You can override `DOCKER_REPO` for testing private repos. +- If `OPENSTUDIO_SHA` is empty, the downloader will attempt to use a generic S3 URL without the SHA. diff --git a/deploy_docker.sh b/deploy_docker.sh index 0de97fa..7678af1 100755 --- a/deploy_docker.sh +++ b/deploy_docker.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash IMAGETAG=${OPENSTUDIO_VERSION}${OPENSTUDIO_VERSION_EXT} -echo "image would be tagged as $IMAGETAG if this were master branch" +echo "default image tag would be $IMAGETAG" IMAGETAG=skip +DOCKER_REPO=${DOCKER_REPO:-nrel/openstudio} # Check branch name for correct tagging if [ "${GITHUB_REF}" == "refs/heads/develop" ]; then @@ -29,12 +30,21 @@ fi # GITHUB_BASE_REF is only set on Pull Request events. Do not build those if [ "${IMAGETAG}" != "skip" ] && [[ -z "${GITHUB_BASE_REF}" ]]; then - echo "Tagging image as $IMAGETAG" + echo "Tagging image as $IMAGETAG and pushing to ${DOCKER_REPO}" echo "$DOCKER_PASS" | docker login -u "$DOCKER_USER" --password-stdin - docker tag openstudio:latest nrel/openstudio:$IMAGETAG; (( exit_status = exit_status || $? )) - docker tag openstudio:latest nrel/openstudio:latest; (( exit_status = exit_status || $? )) - docker push nrel/openstudio:$IMAGETAG; (( exit_status = exit_status || $? )) + # Tag versioned image + docker tag openstudio:latest ${DOCKER_REPO}:$IMAGETAG; (( exit_status = exit_status || $? )) + # Always update latest + docker tag openstudio:latest ${DOCKER_REPO}:latest; (( exit_status = exit_status || $? )) + + # Push versioned tag + docker push ${DOCKER_REPO}:$IMAGETAG; (( exit_status = exit_status || $? )) + # If on develop branch, also push the develop tag pointing to this image + if [ "${IMAGETAG}" == "develop" ] || [ "${GITHUB_REF}" == "refs/heads/develop" ]; then + docker tag openstudio:latest ${DOCKER_REPO}:develop; (( exit_status = exit_status || $? )) + docker push ${DOCKER_REPO}:develop; (( exit_status = exit_status || $? )) + fi exit $exit_status else