From 33bd8d5a330c181841e7c9f0ea5f1c2ed2876f73 Mon Sep 17 00:00:00 2001 From: "Mahadik, Mukul Chandrakant" Date: Fri, 20 Sep 2024 20:42:30 -0700 Subject: [PATCH 1/9] Task A-6: Switching to step outputs instead of GITHUB_ENV Refer to details in cleanup issue: Task A-6: https://github.com/e-mission/e-mission-docs/issues/1082#issuecomment-2364335425 --- .github/workflows/image_build_push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/image_build_push.yml b/.github/workflows/image_build_push.yml index 1847af67b..8580a0b03 100644 --- a/.github/workflows/image_build_push.yml +++ b/.github/workflows/image_build_push.yml @@ -24,7 +24,7 @@ jobs: - name: Get current date # get the date of the build id: date - run: echo "::set-output name=date::$(date +'%Y-%m-%d--%M-%S')" + run: echo "date=$(date +'%Y-%m-%d--%M-%S')" >> "$GITHUB_OUTPUT" #Runs a single command using the runners shell - name: Run a one-line script From 96a8213c14019ddfd4e7c5635c4cf9202964ff0a Mon Sep 17 00:00:00 2001 From: "Mahadik, Mukul Chandrakant" Date: Fri, 20 Sep 2024 21:28:12 -0700 Subject: [PATCH 2/9] Task A-2: Storing latest tag in .env file + Task A-8: Prefix branch name Refer to details in cleanup issue: Task A-2: https://github.com/e-mission/e-mission-docs/issues/1082#issuecomment-2364583414 Storing server tag as well so that artifacts are not needed. Can also remove image tag passed as input in Workflow dispatch POST request. Workflow input also removed in dashboard workflows For now not removing artifacts until the internal script is updated to handle this change. ---- Task A-8: Prefixing branch name to the docker tag along with the date. In the internal script we will not need to maintain the different branch lists as the images will be completely tagged in the external workflows themselves. We can simply use the tags without modifications then. For now, not prefixing the tag to the artifact since we will be removing the artifact anyways. And current internal script works with artifacts. Once I update the internal script, will come back and remove artifacts. --- .github/workflows/image_build_push.yml | 30 +++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/.github/workflows/image_build_push.yml b/.github/workflows/image_build_push.yml index 8580a0b03..4f22ab7f0 100644 --- a/.github/workflows/image_build_push.yml +++ b/.github/workflows/image_build_push.yml @@ -18,6 +18,14 @@ jobs: steps: - uses: actions/checkout@v2 + + - name: Set docker image tags + id: set-tags + run: | + set -a; source .env; set +a + echo "SERVER_IMAGE_TAG=${SERVER_IMAGE_TAG}" >> "$GITHUB_OUTPUT" + echo "Current server image tag (push): ${SERVER_IMAGE_TAG}" + - name: docker login run: | # log into docker hub account docker login -u $DOCKER_USER -p $DOCKER_PASSWORD @@ -40,6 +48,22 @@ jobs: run: | docker push $DOCKER_USER/${GITHUB_REPOSITORY#*/}:${GITHUB_REF##*/}_${{ steps.date.outputs.date }} + - name: Update .env file + run: | + echo "SERVER_IMAGE_TAG=${GITHUB_REF##*/}_${{ steps.date.outputs.date }}" > .env + + - name: Add, Commit, Push changes to .env file + run: | + git config --local user.email "action@github.com" + git config --local user.name "Github Actions bot to update .env with latest tags" + if git diff --quiet; then + echo "Latest timestamp already present in .env file, no changes to commit" + else + git add .env + git commit -m "Updated docker image tags in .env file to the latest timestamp" + git push origin + fi + - name: Create a text file run: | echo ${{ steps.date.outputs.date }} > tag_file.txt @@ -56,9 +80,6 @@ jobs: needs: build runs-on: ubuntu-latest - env: - DOCKER_IMAGE_TAG: ${{ needs.build.outputs.date }} - strategy: matrix: include: @@ -71,7 +92,6 @@ jobs: - uses: actions/checkout@v4 - name: Trigger workflow in admin-dash, public-dash - # TODO: Create Fine-grained token with "Actions: write" permissions run: | curl -L \ -X POST \ @@ -79,4 +99,4 @@ jobs: -H "Authorization: Bearer ${{ secrets.GH_FG_PAT_TAGS }}" \ -H "X-GitHub-Api-Version: 2022-11-28" \ https://api.github.com/repos/${{ matrix.repo }}/actions/workflows/image_build_push.yml/dispatches \ - -d '{"ref":"${{ matrix.branch }}", "inputs": {"docker_image_tag" : "${{ env.DOCKER_IMAGE_TAG }}"}}' + -d '{"ref":"${{ matrix.branch }}"}' From c1917c4118811bed9439996cdf223b6cba3b300d Mon Sep 17 00:00:00 2001 From: "Mahadik, Mukul Chandrakant" Date: Fri, 20 Sep 2024 21:44:11 -0700 Subject: [PATCH 3/9] Task A-7: Removed certificates from external Dockerfile; added internally Refer to issue comment for details: Task A-7: https://github.com/e-mission/e-mission-docs/issues/1082#issuecomment-2364315699 The certificates are relevant to our internal AWS configuration and not needed externally. They can be present externally too without having any major effect. But removing them helps keeping the base image clean. Additionally, anyone working with the code can customize with their own certificates if needed or adopt an approach which doesn't even need certificates in the first place. --- Dockerfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index fcea642fd..04dba77f0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,8 +3,6 @@ FROM ubuntu:jammy-20240227 MAINTAINER K. Shankari (shankari@eecs.berkeley.edu) -ADD https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem /etc/ssl/certs/ - WORKDIR /usr/src/app RUN apt-get -y -qq update From f2f344c452c9158f748c7dc6ae058901cc091600 Mon Sep 17 00:00:00 2001 From: "Mahadik, Mukul Chandrakant" Date: Fri, 20 Sep 2024 21:59:24 -0700 Subject: [PATCH 4/9] Task A-2: Added .env file initialized with the current latest tag --- .env | 1 + 1 file changed, 1 insertion(+) create mode 100644 .env diff --git a/.env b/.env new file mode 100644 index 000000000..b290898cf --- /dev/null +++ b/.env @@ -0,0 +1 @@ +SERVER_IMAGE_TAG=2024-09-20--06-45 From 3a01028463accf790567d7ab55b70a51becd2f77 Mon Sep 17 00:00:00 2001 From: "Mahadik, Mukul Chandrakant" Date: Mon, 23 Sep 2024 14:39:54 -0700 Subject: [PATCH 5/9] Task A-2: Removed artifact upload ; internal script updated Internal script updated as well. Internal PR must be merged as well once these external PR changes merged. --- .github/workflows/image_build_push.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.github/workflows/image_build_push.yml b/.github/workflows/image_build_push.yml index 4f22ab7f0..1afab6fca 100644 --- a/.github/workflows/image_build_push.yml +++ b/.github/workflows/image_build_push.yml @@ -64,18 +64,6 @@ jobs: git push origin fi - - name: Create a text file - run: | - echo ${{ steps.date.outputs.date }} > tag_file.txt - echo "Created tag text file" - - - name: Upload Artifact - uses: actions/upload-artifact@v4 - with: - name: docker-image-tag - path: tag_file.txt - overwrite: true - dispatch: needs: build runs-on: ubuntu-latest From b2382ec6ed26099486379aafa57f5bea9e828074 Mon Sep 17 00:00:00 2001 From: "Mahadik, Mukul Chandrakant" Date: Sun, 29 Sep 2024 12:01:52 -0700 Subject: [PATCH 6/9] Task A-5: Added reusable workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Storing a reusable workflow in the e-mission-server repo. Can decide where to place it in a central location. https://docs.github.com/en/actions/sharing-automations/reusing-workflows It essentially works like a function call in normal programming. The advantage is that we have no repeated code the image build process. All the other repos (join, admin-dash, public-dash) reuse the same workflow file. Additionally, on for future GitHub actions, workflow file related changes, will no longer need to have 3 additional PRs for each repo (join, admin-dash, public-dash). Can simply modify the reusable workflow file as this is the core “function” workflow that is being called. I have added conditional checks that check for the repo name in the reusable workflow file that determine which statements to execute depending on for which repo the workflow is running. This is used for both push events specific to a repo as well as for the workflow dispatch events triggered on pushes to server repo. --- .../workflows/reusable_image_build_push.yml | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 .github/workflows/reusable_image_build_push.yml diff --git a/.github/workflows/reusable_image_build_push.yml b/.github/workflows/reusable_image_build_push.yml new file mode 100644 index 000000000..6bbfcf8e2 --- /dev/null +++ b/.github/workflows/reusable_image_build_push.yml @@ -0,0 +1,141 @@ +name: Reusable Docker Image Build and Push + +on: + workflow_call: + inputs: + repo: + required: true + type: string + branch: + required: true + type: string + +env: + DOCKER_USER: ${{secrets.DOCKER_USER}} + DOCKER_PASSWORD: ${{secrets.DOCKER_PASSWORD}} + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + repository: e-mission/${{ inputs.repo }} + ref: ${{ inputs.branch }} + token: ${{ secrets.GH_FG_PAT_TAGS }} + + - name: Fetch server image tag + id: get-server-tag + run: | + if [ "${{ inputs.repo }}" = "op-admin-dashboard" ] || [ "${{ inputs.repo }}" = "em-public-dashboard" ]; then + response=$(curl -s https://raw.githubusercontent.com/e-mission/e-mission-server/refs/heads/cleanup-cicd/.env) + SERVER_IMAGE_TAG=$(echo "$response" | grep "SERVER_IMAGE_TAG=" | cut -d'=' -f2) + echo "SERVER_IMAGE_TAG=$SERVER_IMAGE_TAG" >> "$GITHUB_OUTPUT" + fi + + - name: Set docker image tags + id: set-tags + run: | + ls -al + set -a; source .env; set +a + if [ "${{ inputs.repo }}" = "nrel-openpath-join-page" ]; then + echo "JOIN_IMAGE_TAG=${JOIN_IMAGE_TAG}" >> "$GITHUB_OUTPUT" + elif [ "${{ inputs.repo }}" = "op-admin-dashboard" ]; then + echo "ADMIN_DASH_IMAGE_TAG=${ADMIN_DASH_IMAGE_TAG}" >> "$GITHUB_OUTPUT" + elif [ "${{ inputs.repo }}" = "em-public-dashboard" ]; then + echo "PUBLIC_DASH_NOTEBOOK_IMAGE_TAG=${PUBLIC_DASH_NOTEBOOK_IMAGE_TAG}" >> "$GITHUB_OUTPUT" + echo "PUBLIC_DASH_FRONTEND_IMAGE_TAG=${PUBLIC_DASH_FRONTEND_IMAGE_TAG}" >> "$GITHUB_OUTPUT" + fi + + - name: Print input docker image tags + run: | + echo "Event name: ${{ github.event_name }}" + if [ "${{ inputs.repo }}" = "nrel-openpath-join-page" ]; then + echo "Current join-page image tag: ${{ steps.set-tags.outputs.JOIN_IMAGE_TAG }}" + elif [ "${{ inputs.repo }}" = "op-admin-dashboard" ]; then + echo "Current admin-dash image tag: ${{ steps.set-tags.outputs.ADMIN_DASH_IMAGE_TAG }}" + echo "Latest server image tag (${{ github.event_name }}): ${{ steps.get-server-tag.outputs.SERVER_IMAGE_TAG }}" + elif [ "${{ inputs.repo }}" = "em-public-dashboard" ]; then + echo "Current notebook image tag (push): ${{ steps.set-tags.outputs.PUBLIC_DASH_NOTEBOOK_IMAGE_TAG }}" + echo "Current frontend image tag (push): ${{ steps.set-tags.outputs.PUBLIC_DASH_FRONTEND_IMAGE_TAG }}" + echo "Latest server image tag (${{ github.event_name }}): ${{ steps.get-server-tag.outputs.SERVER_IMAGE_TAG }}" + fi + + - name: docker login + run: | + docker login -u $DOCKER_USER -p $DOCKER_PASSWORD + + - name: Get current date # get the date of the build + id: date + run: echo "date=$(date +'%Y-%m-%d--%M-%S')" >> "$GITHUB_OUTPUT" + + - name: Run a one-line script + run: echo running image build for repo ${{ inputs.repo }} branch ${{ inputs.branch }} on ${{ steps.date.outputs.date }} + + - name: build docker image + run: | + if [ "${{ inputs.repo }}" = "nrel-openpath-join-page" ]; then + docker build -t $DOCKER_USER/${{ inputs.repo }}:${{ inputs.branch }}_${{ steps.date.outputs.date }} ./frontend + elif [ "${{ inputs.repo }}" = "op-admin-dashboard" ]; then + SERVER_IMAGE_TAG=${{ steps.get-server-tag.outputs.SERVER_IMAGE_TAG }} docker compose -f docker-compose-prod.yml build + elif [ "${{ inputs.repo }}" = "em-public-dashboard" ]; then + SERVER_IMAGE_TAG=${{ steps.get-server-tag.outputs.SERVER_IMAGE_TAG }} docker compose -f docker-compose.yml build + fi + docker images + + - name: rename docker image + run: | + if [ "${{ inputs.repo }}" = "op-admin-dashboard" ]; then + docker image tag e-mission/opdash:0.0.1 $DOCKER_USER/${{ inputs.repo }}:${{ inputs.branch }}_${{ steps.date.outputs.date }} + elif [ "${{ inputs.repo }}" = "em-public-dashboard" ]; then + if [ "${{ github.event_name }}" == "push" ]; then + docker image tag em-pub-dash-prod/frontend:latest $DOCKER_USER/${{ inputs.repo }}_frontend:${{ inputs.branch }}_${{ steps.date.outputs.date }} + fi + docker image tag em-pub-dash-prod/viz-scripts:latest $DOCKER_USER/${{ inputs.repo }}_notebook:${{ inputs.branch }}_${{ steps.date.outputs.date }} + fi + + - name: push docker image + run: | + if [ "${{ inputs.repo }}" = "op-admin-dashboard" ] || [ "${{ inputs.repo }}" = "nrel-openpath-join-page" ]; then + docker push $DOCKER_USER/${{ inputs.repo }}:${{ inputs.branch }}_${{ steps.date.outputs.date }} + elif [ "${{ inputs.repo }}" = "em-public-dashboard" ]; then + if [ "${{ github.event_name }}" == "push" ]; then + docker push $DOCKER_USER/${{ inputs.repo }}_frontend:${{ inputs.branch }}_${{ steps.date.outputs.date }} + fi + docker push $DOCKER_USER/${{ inputs.repo }}_notebook:${{ inputs.branch }}_${{ steps.date.outputs.date }} + fi + + - name: Update .env file + run: | + if [ "${{ inputs.repo }}" = "nrel-openpath-join-page" ]; then + echo "JOIN_IMAGE_TAG=${{ inputs.branch }}_${{ steps.date.outputs.date }}" > .env + elif [ "${{ inputs.repo }}" = "op-admin-dashboard" ]; then + echo "ADMIN_DASH_IMAGE_TAG=${{ inputs.branch }}_${{ steps.date.outputs.date }}" > .env + echo "SERVER_IMAGE_TAG=${{ steps.get-server-tag.outputs.SERVER_IMAGE_TAG }}" >> .env + elif [ "${{ inputs.repo }}" = "em-public-dashboard" ]; then + echo "PUBLIC_DASH_NOTEBOOK_IMAGE_TAG=${{ inputs.branch }}_${{ steps.date.outputs.date }}" > .env + if [ "${{ github.event_name }}" == "push" ]; then + echo "Push event: Update frontend image tag" + echo "PUBLIC_DASH_FRONTEND_IMAGE_TAG=${{ inputs.branch }}_${{ steps.date.outputs.date }}" >> .env + else + echo "Workflow_dispatch: Reuse existing frontend image tag" + echo "PUBLIC_DASH_FRONTEND_IMAGE_TAG=${{ steps.set-tags.outputs.PUBLIC_DASH_FRONTEND_IMAGE_TAG }}" >> .env + fi + echo "SERVER_IMAGE_TAG=${{ steps.get-server-tag.outputs.SERVER_IMAGE_TAG }}" >> .env + fi + cat .env + + - name: Add, Commit, Push changes to .env file + run: | + git config --local user.email "action@github.com" + git config --local user.name "Github Actions bot to update .env with latest tags" + # echo ${{ github.actor }} + if git diff --quiet; then + echo "Latest timestamp already present in .env file, no changes to commit" + else + git add .env + git commit -m "Updated docker image tags in .env file to the latest timestamp" + git push origin + fi + cat .env From d56f6528882d3c050ed5b14103bc326715e535db Mon Sep 17 00:00:00 2001 From: "Mahadik, Mukul Chandrakant" Date: Sun, 29 Sep 2024 16:40:25 -0700 Subject: [PATCH 7/9] Task A-4: Run image_build_push only after tests pass successfully Approach: Converted test-with-docker and test-with-manual-install to reusable workflows. Added them as jobs in image_build_push workflow. Build job in this workflow needs these test jobs as dependencies. ------- Test Workflow run https://github.com/MukuFlash03/e-mission-server/actions/runs/11096277197/job/30825929886 ----- Notes Github actions didn't have out of the box solution for running a workflow based on results of multiple workflows where ALL workflows must have completed successfully. We need this since both the test-with-docker and test-with-manual-install must pass. So this needs an "AND" logic. "workflow_run" is there but this triggers the dependent workflow when either of the workflow dependencies defined as prerequisites are completed. So this has an "OR" logic. https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_run ---- Found an alternative suggestion here: https://stackoverflow.com/a/75597437 This suggests converting the pre-requisite workflows into reusable workflows. These workflows can then be called in jobs in the workflow that needs these workflows to be run before. Finally, these jobs can be added as dependencies for the requisite job. In our scenario, two new jobs are added to the image_build_push.yml for each of the two tests environments. These will run parallelly. Then in the build image job, these jobs are added in the "needs" field, indicating that these jobs must pass successfully before running the build job. ------- Also corrected the branch in reusable workflow for fetching latest server image tag. Need to update in the currently open PRs as well. ------ Also, removed the `push` trigger from the two `test` workflows since the `image_build_push` workflow would also be triggered on a `push` event which in its workflow triggers these two test workflows. Thus if not removed, each test workflow would run twice. --- .github/workflows/image_build_push.yml | 7 +++++++ .github/workflows/reusable_image_build_push.yml | 2 +- .github/workflows/test-with-docker.yml | 4 ++-- .github/workflows/test-with-manual-install.yml | 6 ++---- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/.github/workflows/image_build_push.yml b/.github/workflows/image_build_push.yml index 1afab6fca..bbc092cd8 100644 --- a/.github/workflows/image_build_push.yml +++ b/.github/workflows/image_build_push.yml @@ -10,8 +10,15 @@ env: DOCKER_PASSWORD: ${{secrets.DOCKER_PASSWORD}} jobs: + test-with-docker: + uses: e-mission/e-mission-server/.github/workflows/test-with-docker.yml@master + + test-with-manual-install: + uses: e-mission/e-mission-server/.github/workflows/test-with-manual-install.yml@master + build: runs-on: ubuntu-latest + needs: [test-with-docker, test-with-manual-install] outputs: date: ${{ steps.date.outputs.date }} diff --git a/.github/workflows/reusable_image_build_push.yml b/.github/workflows/reusable_image_build_push.yml index 6bbfcf8e2..5de4eb7eb 100644 --- a/.github/workflows/reusable_image_build_push.yml +++ b/.github/workflows/reusable_image_build_push.yml @@ -29,7 +29,7 @@ jobs: id: get-server-tag run: | if [ "${{ inputs.repo }}" = "op-admin-dashboard" ] || [ "${{ inputs.repo }}" = "em-public-dashboard" ]; then - response=$(curl -s https://raw.githubusercontent.com/e-mission/e-mission-server/refs/heads/cleanup-cicd/.env) + response=$(curl -s https://raw.githubusercontent.com/e-mission/e-mission-server/refs/heads/master/.env) SERVER_IMAGE_TAG=$(echo "$response" | grep "SERVER_IMAGE_TAG=" | cut -d'=' -f2) echo "SERVER_IMAGE_TAG=$SERVER_IMAGE_TAG" >> "$GITHUB_OUTPUT" fi diff --git a/.github/workflows/test-with-docker.yml b/.github/workflows/test-with-docker.yml index 1b54ed5ba..d661e6a02 100644 --- a/.github/workflows/test-with-docker.yml +++ b/.github/workflows/test-with-docker.yml @@ -5,14 +5,14 @@ name: test-with-docker # Controls when the action will run. Triggers the workflow on push or pull request # events but only for the master branch on: - push: - branches: [ master ] pull_request: branches: [ master ] schedule: # * is a special character in YAML so you have to quote this string - cron: '5 4 * * 0' + workflow_call: + # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: # This workflow contains a single job called "build" diff --git a/.github/workflows/test-with-manual-install.yml b/.github/workflows/test-with-manual-install.yml index 4a81eb000..75f920682 100644 --- a/.github/workflows/test-with-manual-install.yml +++ b/.github/workflows/test-with-manual-install.yml @@ -5,10 +5,6 @@ name: ubuntu-only-test-with-manual-install # Controls when the action will run. Triggers the workflow on push or pull request # events but only for the master branch on: - push: - branches: - - master - - gis-based-mode-detection pull_request: branches: - master @@ -17,6 +13,8 @@ on: # * is a special character in YAML so you have to quote this string - cron: '5 4 * * 0' + workflow_call: + # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: # This workflow contains a single job called "build" From 7f390cea4ecf3a767a732a3c103b8f2c1b9b811a Mon Sep 17 00:00:00 2001 From: "Mahadik, Mukul Chandrakant" Date: Tue, 1 Oct 2024 18:25:41 -0700 Subject: [PATCH 8/9] Task A-3: Image build/push on tags/release instead of on every push MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Modified server to use reusable workflow as well - Lots of repeated code in this workflow as well. 2. Added tags as push event triggers - Github documentation for pattern matching - https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#patterns-to-match-branches-and-tags - v[0-9]+.[0-9]+.[0-9]+ 3. Using github context data to select correct branch “git push” command failed in reusable workflow since it wasn’t listing any branch and by default it picked up the tag version and not any branch name. Used ${{ github.event.base_ref }} that has the source branch from which the release tag was created. - https://github.com/orgs/community/discussions/27154 - https://github.com/orgs/community/discussions/26243 Needed to extract only branch name to ignore “ref/heads/“ Added a separate job that extracts this using bash commands - https://stackoverflow.com/questions/16623835/remove-a-fixed-prefix-suffix-from-a-string-in-bash ——— 4. Server workflow runs on both push:branches and push:tags events. This is because we want tests to run before push. Using “github.ref_type” for checking whether event type was “branch” or “tag” - Documentation - https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/accessing-contextual-information-about-workflow-runs Server run was failing: "git push” needs the branch name - https://github.com/MukuFlash03/e-mission-server/actions/runs/11134355511/job/30942421505 - Add branch name in reusable workflow The error message in the run logs suggest using this: - https://github.com/MukuFlash03/e-mission-server/actions/runs/11134355511/job/30942421505 - $ git push origin HEAD: ———— 5. Using github.ref_type to check “branch” or “tag” and select correct branch When server release is created, it triggers dispatch to other workflows. However these don’t have “github.ref_type” = “tag” in this case but instead “github.ref_type” = “branch”. This case github.event.base_ref value to be empty, hence branch name extraction didn’t work. I’m using the ref_type to pass either GITHUB_REF or the extraction logic using github.event.base_ref. This is done in the workflows that call reusable workflow. The check should be fine since ref_type has only two values: branch or tag - https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/accessing-contextual-information-about-workflow-runs --- .github/workflows/image_build_push.yml | 75 +++++++------------ .../workflows/reusable_image_build_push.yml | 40 +++++----- 2 files changed, 47 insertions(+), 68 deletions(-) diff --git a/.github/workflows/image_build_push.yml b/.github/workflows/image_build_push.yml index bbc092cd8..89d8eed16 100644 --- a/.github/workflows/image_build_push.yml +++ b/.github/workflows/image_build_push.yml @@ -3,6 +3,8 @@ name: docker image on: push: branches: [ master, gis-based-mode-detection ] + tags: + - "v[0-9]+.[0-9]+.[0-9]+" #Dockerhub credentials are set as environment variables env: @@ -16,60 +18,33 @@ jobs: test-with-manual-install: uses: e-mission/e-mission-server/.github/workflows/test-with-manual-install.yml@master - build: + get-branch-name: runs-on: ubuntu-latest - needs: [test-with-docker, test-with-manual-install] - outputs: - date: ${{ steps.date.outputs.date }} - + branch_name: ${{ steps.get-branch-name.outputs.branch_name }} steps: - - uses: actions/checkout@v2 - - - name: Set docker image tags - id: set-tags - run: | - set -a; source .env; set +a - echo "SERVER_IMAGE_TAG=${SERVER_IMAGE_TAG}" >> "$GITHUB_OUTPUT" - echo "Current server image tag (push): ${SERVER_IMAGE_TAG}" - - - name: docker login - run: | # log into docker hub account - docker login -u $DOCKER_USER -p $DOCKER_PASSWORD - - - name: Get current date # get the date of the build - id: date - run: echo "date=$(date +'%Y-%m-%d--%M-%S')" >> "$GITHUB_OUTPUT" + - name: Get branch name based on ref_type + id: get-branch-name + run: | + echo "Ref: ${{ github.ref }}" + echo "Ref name: ${{ github.ref_name }}" + echo "Ref type: ${{ github.ref_type }}" + echo "Github event base ref: ${{ github.event.base_ref }}" + if [ "${{ github.ref_type }}" == "tag" ]; then + base_ref=${{ github.event.base_ref }} + echo "branch_name=${base_ref#refs/heads/}" >> "$GITHUB_OUTPUT" + elif [ "${{ github.ref_type }}" == "branch" ]; then + echo "branch_name=${GITHUB_REF##*/}" >> "$GITHUB_OUTPUT" + fi - #Runs a single command using the runners shell - - name: Run a one-line script - run: echo running in repo ${GITHUB_REPOSITORY#*/} branch ${GITHUB_REF##*/} on ${{ steps.date.outputs.date }} - - # Runs a set of commands using the runners shell - - name: build docker image - run: | - docker build -t $DOCKER_USER/${GITHUB_REPOSITORY#*/}:${GITHUB_REF##*/}_${{ steps.date.outputs.date }} . - docker images - - - name: push docker image - run: | - docker push $DOCKER_USER/${GITHUB_REPOSITORY#*/}:${GITHUB_REF##*/}_${{ steps.date.outputs.date }} - - - name: Update .env file - run: | - echo "SERVER_IMAGE_TAG=${GITHUB_REF##*/}_${{ steps.date.outputs.date }}" > .env - - - name: Add, Commit, Push changes to .env file - run: | - git config --local user.email "action@github.com" - git config --local user.name "Github Actions bot to update .env with latest tags" - if git diff --quiet; then - echo "Latest timestamp already present in .env file, no changes to commit" - else - git add .env - git commit -m "Updated docker image tags in .env file to the latest timestamp" - git push origin - fi + build: + if: ${{ !contains(github.event.head_commit.author.name, 'Github Actions bot to update .env with latest tags') && github.ref_type == 'tag' }} + needs: [test-with-docker, test-with-manual-install, get-branch-name] + uses: e-mission/e-mission-server/.github/workflows/reusable_image_build_push.yml@master + with: + repo: ${{ github.event.repository.name }} + branch: ${{ needs.get-branch-name.outputs.branch_name }} + secrets: inherit dispatch: needs: build diff --git a/.github/workflows/reusable_image_build_push.yml b/.github/workflows/reusable_image_build_push.yml index 5de4eb7eb..6cc591f88 100644 --- a/.github/workflows/reusable_image_build_push.yml +++ b/.github/workflows/reusable_image_build_push.yml @@ -25,21 +25,21 @@ jobs: ref: ${{ inputs.branch }} token: ${{ secrets.GH_FG_PAT_TAGS }} - - name: Fetch server image tag - id: get-server-tag + - name: Fetch latest server image tag + if: ${{ inputs.repo == 'op-admin-dashboard' || inputs.repo == 'em-public-dashboard' }} run: | - if [ "${{ inputs.repo }}" = "op-admin-dashboard" ] || [ "${{ inputs.repo }}" = "em-public-dashboard" ]; then - response=$(curl -s https://raw.githubusercontent.com/e-mission/e-mission-server/refs/heads/master/.env) - SERVER_IMAGE_TAG=$(echo "$response" | grep "SERVER_IMAGE_TAG=" | cut -d'=' -f2) - echo "SERVER_IMAGE_TAG=$SERVER_IMAGE_TAG" >> "$GITHUB_OUTPUT" - fi + response=$(curl -s https://raw.githubusercontent.com/e-mission/e-mission-server/refs/heads/master/.env) + SERVER_IMAGE_TAG=$(echo "$response" | grep "SERVER_IMAGE_TAG=" | cut -d'=' -f2) + echo "SERVER_IMAGE_TAG=$SERVER_IMAGE_TAG" >> "$GITHUB_OUTPUT" - name: Set docker image tags id: set-tags run: | ls -al set -a; source .env; set +a - if [ "${{ inputs.repo }}" = "nrel-openpath-join-page" ]; then + if [ "${{ inputs.repo }}" = "e-mission-server" ]; then + echo "SERVER_IMAGE_TAG=${SERVER_IMAGE_TAG}" >> "$GITHUB_OUTPUT" + elif [ "${{ inputs.repo }}" = "nrel-openpath-join-page" ]; then echo "JOIN_IMAGE_TAG=${JOIN_IMAGE_TAG}" >> "$GITHUB_OUTPUT" elif [ "${{ inputs.repo }}" = "op-admin-dashboard" ]; then echo "ADMIN_DASH_IMAGE_TAG=${ADMIN_DASH_IMAGE_TAG}" >> "$GITHUB_OUTPUT" @@ -47,11 +47,13 @@ jobs: echo "PUBLIC_DASH_NOTEBOOK_IMAGE_TAG=${PUBLIC_DASH_NOTEBOOK_IMAGE_TAG}" >> "$GITHUB_OUTPUT" echo "PUBLIC_DASH_FRONTEND_IMAGE_TAG=${PUBLIC_DASH_FRONTEND_IMAGE_TAG}" >> "$GITHUB_OUTPUT" fi - + - name: Print input docker image tags run: | echo "Event name: ${{ github.event_name }}" - if [ "${{ inputs.repo }}" = "nrel-openpath-join-page" ]; then + if [ "${{ inputs.repo }}" = "e-mission-server" ]; then + echo "Current server image tag: ${{ steps.set-tags.outputs.SERVER_IMAGE_TAG }}" + elif [ "${{ inputs.repo }}" = "nrel-openpath-join-page" ]; then echo "Current join-page image tag: ${{ steps.set-tags.outputs.JOIN_IMAGE_TAG }}" elif [ "${{ inputs.repo }}" = "op-admin-dashboard" ]; then echo "Current admin-dash image tag: ${{ steps.set-tags.outputs.ADMIN_DASH_IMAGE_TAG }}" @@ -75,7 +77,9 @@ jobs: - name: build docker image run: | - if [ "${{ inputs.repo }}" = "nrel-openpath-join-page" ]; then + if [ "${{ inputs.repo }}" = "e-mission-server" ]; then + docker build -t $DOCKER_USER/${{ inputs.repo }}:${{ inputs.branch }}_${{ steps.date.outputs.date }} . + elif [ "${{ inputs.repo }}" = "nrel-openpath-join-page" ]; then docker build -t $DOCKER_USER/${{ inputs.repo }}:${{ inputs.branch }}_${{ steps.date.outputs.date }} ./frontend elif [ "${{ inputs.repo }}" = "op-admin-dashboard" ]; then SERVER_IMAGE_TAG=${{ steps.get-server-tag.outputs.SERVER_IMAGE_TAG }} docker compose -f docker-compose-prod.yml build @@ -97,18 +101,20 @@ jobs: - name: push docker image run: | - if [ "${{ inputs.repo }}" = "op-admin-dashboard" ] || [ "${{ inputs.repo }}" = "nrel-openpath-join-page" ]; then - docker push $DOCKER_USER/${{ inputs.repo }}:${{ inputs.branch }}_${{ steps.date.outputs.date }} - elif [ "${{ inputs.repo }}" = "em-public-dashboard" ]; then + if [ "${{ inputs.repo }}" = "em-public-dashboard" ]; then if [ "${{ github.event_name }}" == "push" ]; then docker push $DOCKER_USER/${{ inputs.repo }}_frontend:${{ inputs.branch }}_${{ steps.date.outputs.date }} fi docker push $DOCKER_USER/${{ inputs.repo }}_notebook:${{ inputs.branch }}_${{ steps.date.outputs.date }} + else + docker push $DOCKER_USER/${{ inputs.repo }}:${{ inputs.branch }}_${{ steps.date.outputs.date }} fi - + - name: Update .env file run: | - if [ "${{ inputs.repo }}" = "nrel-openpath-join-page" ]; then + if [ "${{ inputs.repo }}" = "e-mission-server" ]; then + echo "SERVER_IMAGE_TAG=${{ inputs.branch }}_${{ steps.date.outputs.date }}" > .env + elif [ "${{ inputs.repo }}" = "nrel-openpath-join-page" ]; then echo "JOIN_IMAGE_TAG=${{ inputs.branch }}_${{ steps.date.outputs.date }}" > .env elif [ "${{ inputs.repo }}" = "op-admin-dashboard" ]; then echo "ADMIN_DASH_IMAGE_TAG=${{ inputs.branch }}_${{ steps.date.outputs.date }}" > .env @@ -130,7 +136,6 @@ jobs: run: | git config --local user.email "action@github.com" git config --local user.name "Github Actions bot to update .env with latest tags" - # echo ${{ github.actor }} if git diff --quiet; then echo "Latest timestamp already present in .env file, no changes to commit" else @@ -138,4 +143,3 @@ jobs: git commit -m "Updated docker image tags in .env file to the latest timestamp" git push origin fi - cat .env From dcdd42f85460a0c38f54ab2edbefde96d750303f Mon Sep 17 00:00:00 2001 From: "Mahadik, Mukul Chandrakant" Date: Tue, 8 Oct 2024 12:38:06 -0700 Subject: [PATCH 9/9] Task A-1: Switching to GHCR + Task A-3: Image build/push on release and not push MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task A-3: Image build/push on release instead of on every push 1. Re-building on releases instead of tags - Earlier I had set the trigger event as tags but this would mean any time we create a new tag the workflow would be triggered. - Instead, we are actually creating releases and not tags through the UI. - Hence change the trigger event to releases, specifically “published” releases. ------ 2. Both Tests and Build will happen for push events - Tests: We need tests to confirm everything works before merging. - Build: Similarly, even though tests might pass, the image build could fail due to issues in Dockerfile or any files used in Dockerfile. - Hence to ensure that the final image that is pushed is correctly built, and we can have a correct version released, running both tests and build for push events. ------ 3. Dispatch only runs on releases identified by ref_type == tag. - Dispatch depends on build and since we now have build running for both push and release events, dispatch would also run for both. - Hence restricting dispatch to run only on release events by using the ref_type check which has the value “tag” for releases and “branch” for pushes on any branch. ------- 4. Additional version increment steps + Creating incremented version tags and releases in workflow - Manually creating new release through UI would trigger the workflows for all the repos and the new tag would be updated to the tag version set in the UI. This would be updated in the .env files as well. - But for the workflow_dispatch as well, we need to handle creating a new tag and release for the dependent cascading images in the dashboard repositories. - For this, I’m fetching the latest and 2nd latest server releases and checking for the type of SemVer release (major/minor/patch). Based on the type, similar version increment would occur for the dependent images. - Depending on the event type (release / workflow_dispatch), either the tag created through the UI or the incremented tag version would be chosen as the new tag, respectively for each of the two trigger event types. - This new tag is also written to the .env file. - Finally, a new release is created based on this newly created tag in the workflow. ---------------------- Task A-1: Switch to storing images in GHCR 1. Changes to Dockerfile - Needed to add LABEL layer to ensure that the docker image is connected to the correct repository. - For dashboard images that are dependent on the server image, changed to pull from GHCR. 2. Workflow file - Login action used to login to GHCR. - Building, Renaming, Pushing images with GHCR tag. - Appropriate version tag names used depending on whether trigger event was release or workflow_dispatch. --- .github/workflows/image_build_push.yml | 19 +- .../workflows/reusable_image_build_push.yml | 196 +++++++++++++++--- Dockerfile | 2 + 3 files changed, 176 insertions(+), 41 deletions(-) diff --git a/.github/workflows/image_build_push.yml b/.github/workflows/image_build_push.yml index 89d8eed16..3bc40776a 100644 --- a/.github/workflows/image_build_push.yml +++ b/.github/workflows/image_build_push.yml @@ -2,9 +2,9 @@ name: docker image on: push: - branches: [ master, gis-based-mode-detection ] - tags: - - "v[0-9]+.[0-9]+.[0-9]+" + branches: [ master, gis-based-mode-detection, cleanup-cicd ] + release: + types: [published] #Dockerhub credentials are set as environment variables env: @@ -26,19 +26,15 @@ jobs: - name: Get branch name based on ref_type id: get-branch-name run: | - echo "Ref: ${{ github.ref }}" - echo "Ref name: ${{ github.ref_name }}" - echo "Ref type: ${{ github.ref_type }}" - echo "Github event base ref: ${{ github.event.base_ref }}" if [ "${{ github.ref_type }}" == "tag" ]; then - base_ref=${{ github.event.base_ref }} - echo "branch_name=${base_ref#refs/heads/}" >> "$GITHUB_OUTPUT" + target_branch=${{ github.event.release.target_commitish }} + echo "branch_name=${target_branch}" >> "$GITHUB_OUTPUT" elif [ "${{ github.ref_type }}" == "branch" ]; then echo "branch_name=${GITHUB_REF##*/}" >> "$GITHUB_OUTPUT" fi build: - if: ${{ !contains(github.event.head_commit.author.name, 'Github Actions bot to update .env with latest tags') && github.ref_type == 'tag' }} + if: ${{ !contains(github.event.head_commit.author.name, 'Github Actions bot') }} needs: [test-with-docker, test-with-manual-install, get-branch-name] uses: e-mission/e-mission-server/.github/workflows/reusable_image_build_push.yml@master with: @@ -47,7 +43,8 @@ jobs: secrets: inherit dispatch: - needs: build + if: ${{ github.ref_type == 'tag' }} + needs: [build] runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/reusable_image_build_push.yml b/.github/workflows/reusable_image_build_push.yml index 6cc591f88..a2d1760d3 100644 --- a/.github/workflows/reusable_image_build_push.yml +++ b/.github/workflows/reusable_image_build_push.yml @@ -24,14 +24,103 @@ jobs: repository: e-mission/${{ inputs.repo }} ref: ${{ inputs.branch }} token: ${{ secrets.GH_FG_PAT_TAGS }} - + fetch-depth: 0 + + - name: Fetch latest repository release tag + id: fetch-latest-release-tags + run: | + response=$(curl -L -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.GH_FG_PAT_TAGS }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "https://api.github.com/repos/e-mission/${{ inputs.repo }}/releases/latest") + + tag_name=$(echo "$response" | jq -r '.tag_name') + target_commitish=$(echo "$response" | jq -r '.target_commitish') + + echo "tag_name=$(echo "$response" | jq -r '.tag_name')" >> "$GITHUB_OUTPUT" + echo "target_commitish=$(echo "$response" | jq -r '.target_commitish')" >> "$GITHUB_OUTPUT" + - name: Fetch latest server image tag + id: get-server-tag if: ${{ inputs.repo == 'op-admin-dashboard' || inputs.repo == 'em-public-dashboard' }} run: | - response=$(curl -s https://raw.githubusercontent.com/e-mission/e-mission-server/refs/heads/master/.env) - SERVER_IMAGE_TAG=$(echo "$response" | grep "SERVER_IMAGE_TAG=" | cut -d'=' -f2) - echo "SERVER_IMAGE_TAG=$SERVER_IMAGE_TAG" >> "$GITHUB_OUTPUT" + response=$(curl -L -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.GH_FG_PAT_TAGS }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "https://api.github.com/repos/e-mission/e-mission-server/releases") + + tags=$(echo "$response" | jq -r '.[].tag_name') + current_server_release_tag=$(echo "$tags" | sort -V | tail -n 1) + previous_server_release_tag=$(echo "$tags" | sort -V | tail -n 2 | head -n 1) + + echo "SERVER_IMAGE_TAG=$current_server_release_tag" >> "$GITHUB_OUTPUT" + echo "PREVIOUS_SERVER_TAG=$previous_server_release_tag" >> "$GITHUB_OUTPUT" + + echo "Latest server release tag: $current_server_release_tag" + echo "Previous server release tag: $previous_server_release_tag" + + - name: Bump up release tag + if: ${{ github.event_name == 'workflow_dispatch' }} + id: increment-release-tag + run: | + current_server_tag=${{ steps.get-server-tag.outputs.SERVER_IMAGE_TAG }} + previous_server_tag=${{ steps.get-server-tag.outputs.PREVIOUS_SERVER_TAG }} + + echo "Current server tag: $current_server_tag" + echo "Previous server tag: $previous_server_tag" + + current_server_tag_only=${current_server_tag:1} + previous_server_tag_only=${previous_server_tag:1} + + IFS='.' read -r -a current <<< "${current_server_tag_only}" + IFS='.' read -r -a previous <<< "${previous_server_tag_only}" + + if [[ ${#current[@]} -eq 3 && ${#previous[@]} -eq 3 ]]; then + if [ "${current[0]}" -gt "${previous[0]}" ]; then + version_change=major + elif [ "${current[0]}" -eq "${previous[0]}" ] && [ "${current[1]}" -gt "${previous[1]}" ]; then + version_change=minor + elif [ "${current[0]}" -eq "${previous[0]}" ] && [ "${current[1]}" -eq "${previous[1]}" ] && [ "${current[2]}" -gt "${previous[2]}" ]; then + version_change=patch + fi + else + echo "Version format error" + exit 1 + fi + + echo "name=version_change::$version_change" + + current_repo_version=${{ steps.fetch-latest-release-tags.outputs.tag_name }} + current_repo_version_only=${current_repo_version:1} + + IFS='.' read -r -a version_parts <<< "${current_repo_version_only}" + case "$version_change" in + major) + version_parts[0]=$((version_parts[0] + 1)) + version_parts[1]=0 + version_parts[2]=0 + ;; + minor) + version_parts[1]=$((version_parts[1] + 1)) + version_parts[2]=0 + ;; + patch) + version_parts[2]=$((version_parts[2] + 1)) + ;; + esac + + new_repo_version="v${version_parts[0]}.${version_parts[1]}.${version_parts[2]}" + echo "new_repo_version::$new_repo_version" + echo "new_repo_version=$new_repo_version" >> "$GITHUB_OUTPUT" + + - name: Print fetched tags + run: | + echo "Current image tag: ${{ steps.fetch-latest-release-tags.outputs.tag_name }} ; target_commit branch: ${{ steps.fetch-latest-release-tags.outputs.target_commitish }}" + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + echo "Incremented image tag: ${{ steps.increment-release-tag.outputs.new_repo_version }}" + fi + - name: Set docker image tags id: set-tags run: | @@ -39,18 +128,22 @@ jobs: set -a; source .env; set +a if [ "${{ inputs.repo }}" = "e-mission-server" ]; then echo "SERVER_IMAGE_TAG=${SERVER_IMAGE_TAG}" >> "$GITHUB_OUTPUT" + echo "CURRENT_REPO_TAG=${SERVER_IMAGE_TAG}" >> "$GITHUB_OUTPUT" elif [ "${{ inputs.repo }}" = "nrel-openpath-join-page" ]; then echo "JOIN_IMAGE_TAG=${JOIN_IMAGE_TAG}" >> "$GITHUB_OUTPUT" + echo "CURRENT_REPO_TAG=${JOIN_IMAGE_TAG}" >> "$GITHUB_OUTPUT" elif [ "${{ inputs.repo }}" = "op-admin-dashboard" ]; then echo "ADMIN_DASH_IMAGE_TAG=${ADMIN_DASH_IMAGE_TAG}" >> "$GITHUB_OUTPUT" + echo "CURRENT_REPO_TAG=${ADMIN_DASH_IMAGE_TAG}" >> "$GITHUB_OUTPUT" elif [ "${{ inputs.repo }}" = "em-public-dashboard" ]; then + echo "CURRENT_REPO_TAG=${PUBLIC_DASH_NOTEBOOK_IMAGE_TAG}" >> "$GITHUB_OUTPUT" echo "PUBLIC_DASH_NOTEBOOK_IMAGE_TAG=${PUBLIC_DASH_NOTEBOOK_IMAGE_TAG}" >> "$GITHUB_OUTPUT" echo "PUBLIC_DASH_FRONTEND_IMAGE_TAG=${PUBLIC_DASH_FRONTEND_IMAGE_TAG}" >> "$GITHUB_OUTPUT" fi - name: Print input docker image tags run: | - echo "Event name: ${{ github.event_name }}" + echo "Event name: ${{ github.event_name }} | ${{ github.ref_type }}" if [ "${{ inputs.repo }}" = "e-mission-server" ]; then echo "Current server image tag: ${{ steps.set-tags.outputs.SERVER_IMAGE_TAG }}" elif [ "${{ inputs.repo }}" = "nrel-openpath-join-page" ]; then @@ -59,14 +152,17 @@ jobs: echo "Current admin-dash image tag: ${{ steps.set-tags.outputs.ADMIN_DASH_IMAGE_TAG }}" echo "Latest server image tag (${{ github.event_name }}): ${{ steps.get-server-tag.outputs.SERVER_IMAGE_TAG }}" elif [ "${{ inputs.repo }}" = "em-public-dashboard" ]; then - echo "Current notebook image tag (push): ${{ steps.set-tags.outputs.PUBLIC_DASH_NOTEBOOK_IMAGE_TAG }}" - echo "Current frontend image tag (push): ${{ steps.set-tags.outputs.PUBLIC_DASH_FRONTEND_IMAGE_TAG }}" + echo "Current notebook image tag: ${{ steps.set-tags.outputs.PUBLIC_DASH_NOTEBOOK_IMAGE_TAG }}" + echo "Current frontend image tag: ${{ steps.set-tags.outputs.PUBLIC_DASH_FRONTEND_IMAGE_TAG }}" echo "Latest server image tag (${{ github.event_name }}): ${{ steps.get-server-tag.outputs.SERVER_IMAGE_TAG }}" fi - - name: docker login - run: | - docker login -u $DOCKER_USER -p $DOCKER_PASSWORD + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Get current date # get the date of the build id: date @@ -78,9 +174,9 @@ jobs: - name: build docker image run: | if [ "${{ inputs.repo }}" = "e-mission-server" ]; then - docker build -t $DOCKER_USER/${{ inputs.repo }}:${{ inputs.branch }}_${{ steps.date.outputs.date }} . + docker build -t ghcr.io/e-mission/${{ inputs.repo }}:${{ steps.fetch-latest-release-tags.outputs.tag_name }} . elif [ "${{ inputs.repo }}" = "nrel-openpath-join-page" ]; then - docker build -t $DOCKER_USER/${{ inputs.repo }}:${{ inputs.branch }}_${{ steps.date.outputs.date }} ./frontend + docker build -t ghcr.io/e-mission/${{ inputs.repo }}:${{ steps.fetch-latest-release-tags.outputs.tag_name }} ./frontend elif [ "${{ inputs.repo }}" = "op-admin-dashboard" ]; then SERVER_IMAGE_TAG=${{ steps.get-server-tag.outputs.SERVER_IMAGE_TAG }} docker compose -f docker-compose-prod.yml build elif [ "${{ inputs.repo }}" = "em-public-dashboard" ]; then @@ -89,50 +185,90 @@ jobs: docker images - name: rename docker image + if: ${{ github.ref_type == 'tag' || github.event_name == 'workflow_dispatch' }} run: | - if [ "${{ inputs.repo }}" = "op-admin-dashboard" ]; then - docker image tag e-mission/opdash:0.0.1 $DOCKER_USER/${{ inputs.repo }}:${{ inputs.branch }}_${{ steps.date.outputs.date }} + if [ "${{ inputs.repo }}" = "op-admin-dashboard" ]; then + if [ "${{ github.event_name }}" == "release" ]; then + docker tag e-mission/opdash:0.0.1 ghcr.io/e-mission/${{ inputs.repo }}:${{ steps.fetch-latest-release-tags.outputs.tag_name }} + elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + docker tag e-mission/opdash:0.0.1 ghcr.io/e-mission/${{ inputs.repo }}:${{ steps.increment-release-tag.outputs.new_repo_version }} + fi elif [ "${{ inputs.repo }}" = "em-public-dashboard" ]; then - if [ "${{ github.event_name }}" == "push" ]; then - docker image tag em-pub-dash-prod/frontend:latest $DOCKER_USER/${{ inputs.repo }}_frontend:${{ inputs.branch }}_${{ steps.date.outputs.date }} + if [ "${{ github.event_name }}" == "release" ]; then + docker tag em-pub-dash-prod/frontend:latest ghcr.io/e-mission/${{ inputs.repo }}_frontend:${{ steps.fetch-latest-release-tags.outputs.tag_name }} + docker tag em-pub-dash-prod/viz-scripts:latest ghcr.io/e-mission/${{ inputs.repo }}_notebook:${{ steps.fetch-latest-release-tags.outputs.tag_name }} + elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + docker tag em-pub-dash-prod/viz-scripts:latest ghcr.io/e-mission/${{ inputs.repo }}_notebook:${{ steps.increment-release-tag.outputs.new_repo_version }} fi - docker image tag em-pub-dash-prod/viz-scripts:latest $DOCKER_USER/${{ inputs.repo }}_notebook:${{ inputs.branch }}_${{ steps.date.outputs.date }} fi - name: push docker image + if: ${{ github.ref_type == 'tag' || github.event_name == 'workflow_dispatch' }} run: | if [ "${{ inputs.repo }}" = "em-public-dashboard" ]; then - if [ "${{ github.event_name }}" == "push" ]; then - docker push $DOCKER_USER/${{ inputs.repo }}_frontend:${{ inputs.branch }}_${{ steps.date.outputs.date }} + if [ "${{ github.event_name }}" == "release" ]; then + docker push ghcr.io/e-mission/${{ inputs.repo }}_frontend:${{ steps.fetch-latest-release-tags.outputs.tag_name }} + docker push ghcr.io/e-mission/${{ inputs.repo }}_notebook:${{ steps.fetch-latest-release-tags.outputs.tag_name }} + elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + docker push ghcr.io/e-mission/${{ inputs.repo }}_notebook:${{ steps.increment-release-tag.outputs.new_repo_version }} + fi + elif [ "${{ inputs.repo }}" = "op-admin-dashboard" ]; then + if [ "${{ github.event_name }}" == "release" ]; then + docker push ghcr.io/e-mission/${{ inputs.repo }}:${{ steps.fetch-latest-release-tags.outputs.tag_name }} + elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + docker push ghcr.io/e-mission/${{ inputs.repo }}:${{ steps.increment-release-tag.outputs.new_repo_version }} fi - docker push $DOCKER_USER/${{ inputs.repo }}_notebook:${{ inputs.branch }}_${{ steps.date.outputs.date }} else - docker push $DOCKER_USER/${{ inputs.repo }}:${{ inputs.branch }}_${{ steps.date.outputs.date }} + docker push ghcr.io/e-mission/${{ inputs.repo }}:${{ steps.fetch-latest-release-tags.outputs.tag_name }} fi - name: Update .env file + if: ${{ github.ref_type == 'tag' || github.event_name == 'workflow_dispatch' }} run: | if [ "${{ inputs.repo }}" = "e-mission-server" ]; then - echo "SERVER_IMAGE_TAG=${{ inputs.branch }}_${{ steps.date.outputs.date }}" > .env + echo "SERVER_IMAGE_TAG=${{ steps.fetch-latest-release-tags.outputs.tag_name }}" > .env elif [ "${{ inputs.repo }}" = "nrel-openpath-join-page" ]; then - echo "JOIN_IMAGE_TAG=${{ inputs.branch }}_${{ steps.date.outputs.date }}" > .env + echo "JOIN_IMAGE_TAG=${{ steps.fetch-latest-release-tags.outputs.tag_name }}" > .env elif [ "${{ inputs.repo }}" = "op-admin-dashboard" ]; then - echo "ADMIN_DASH_IMAGE_TAG=${{ inputs.branch }}_${{ steps.date.outputs.date }}" > .env + if [ "${{ github.event_name }}" == "release" ]; then + echo "ADMIN_DASH_IMAGE_TAG=${{ steps.fetch-latest-release-tags.outputs.tag_name }}" > .env + elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + echo "ADMIN_DASH_IMAGE_TAG=${{ steps.increment-release-tag.outputs.new_repo_version }}" > .env + fi echo "SERVER_IMAGE_TAG=${{ steps.get-server-tag.outputs.SERVER_IMAGE_TAG }}" >> .env elif [ "${{ inputs.repo }}" = "em-public-dashboard" ]; then - echo "PUBLIC_DASH_NOTEBOOK_IMAGE_TAG=${{ inputs.branch }}_${{ steps.date.outputs.date }}" > .env - if [ "${{ github.event_name }}" == "push" ]; then - echo "Push event: Update frontend image tag" - echo "PUBLIC_DASH_FRONTEND_IMAGE_TAG=${{ inputs.branch }}_${{ steps.date.outputs.date }}" >> .env - else - echo "Workflow_dispatch: Reuse existing frontend image tag" + if [ "${{ github.event_name }}" == "release" ]; then + echo "PUBLIC_DASH_NOTEBOOK_IMAGE_TAG=${{ steps.fetch-latest-release-tags.outputs.tag_name }}" > .env + echo "PUBLIC_DASH_FRONTEND_IMAGE_TAG=${{ steps.fetch-latest-release-tags.outputs.tag_name }}" >> .env + elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + echo "PUBLIC_DASH_NOTEBOOK_IMAGE_TAG=${{ steps.increment-release-tag.outputs.new_repo_version }}" > .env echo "PUBLIC_DASH_FRONTEND_IMAGE_TAG=${{ steps.set-tags.outputs.PUBLIC_DASH_FRONTEND_IMAGE_TAG }}" >> .env fi echo "SERVER_IMAGE_TAG=${{ steps.get-server-tag.outputs.SERVER_IMAGE_TAG }}" >> .env fi cat .env + - name: Create, Push new tag and Publish release + if: ${{ github.event_name == 'workflow_dispatch' }} + run: | + git config --local user.email "action@github.com" + git config --local user.name "Github Actions bot to create new tags and publish releases" + git tag -a ${{ steps.increment-release-tag.outputs.new_repo_version }} -m"$(git log --pretty=format:%s ${{ steps.set-tags.outputs.CURRENT_REPO_TAG }}...HEAD --no-merges)" + git push origin ${{ steps.increment-release-tag.outputs.new_repo_version }} + + echo "Logging latest created and pushed tag" + git describe --abbrev=0 --tags + + curl -L \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.GH_FG_PAT_TAGS }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/e-mission/${{ inputs.repo }}/releases \ + -d '{"tag_name":"${{ steps.increment-release-tag.outputs.new_repo_version }}","target_commitish":"${{ inputs.branch }}","name":"${{ steps.increment-release-tag.outputs.new_repo_version }}","body":"Triggered on e-mission-server new release. Bumping up release version.","generate_release_notes":true}' + - name: Add, Commit, Push changes to .env file + if: ${{ github.ref_type == 'tag' || github.event_name == 'workflow_dispatch' }} run: | git config --local user.email "action@github.com" git config --local user.name "Github Actions bot to update .env with latest tags" diff --git a/Dockerfile b/Dockerfile index 04dba77f0..3d2cf2da8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,6 +3,8 @@ FROM ubuntu:jammy-20240227 MAINTAINER K. Shankari (shankari@eecs.berkeley.edu) +LABEL org.opencontainers.image.source=https://github.com/e-mission/e-mission-server + WORKDIR /usr/src/app RUN apt-get -y -qq update