diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..94a97fe --- /dev/null +++ b/.dockerignore @@ -0,0 +1,9 @@ +.git +.github + +.dockerignore +.gitignore +CHANGELOG.md +Dockerfile +Jenkinsfile +README.md \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..7ed32d6 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,95 @@ +name: release-chebi-update ci + +on: + workflow_dispatch: + pull_request: + types: + - opened + - synchronize + push: + branches: + - main + +permissions: + id-token: write + contents: read + +jobs: + lint: + if: ${{ github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' }} + runs-on: ubuntu-latest + env: + REPO_DIR: /opt/release-chebi-update + steps: + - uses: actions/checkout@v4 + + - name: Run lint + run: | + docker build --build-arg REPO_DIR="$REPO_DIR" --target setup-env -t lint-image . + docker run --name lint-container lint-image + + - name: Display lint errors + if: failure() + run: | + docker cp lint-container:"$REPO_DIR"/lint.log . + while IFS= read -r LINT_MSG; do echo "::warning::${LINT_MSG}"; done < lint.log + exit 1 + + docker-build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: docker/setup-buildx-action@v3 + + - uses: docker/build-push-action@v5 + with: + context: . + file: Dockerfile + tags: tmp-tag + outputs: type=docker,dest=/tmp/image.tar + + - uses: actions/upload-artifact@v4 + with: + name: image-artifact + path: /tmp/image.tar + + docker-push: + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + needs: docker-build + runs-on: ubuntu-latest + steps: + - uses: actions/download-artifact@v4 + with: + name: image-artifact + path: /tmp + + - id: get-hash + run: | + FULL_SHA=${{ github.sha }} + echo "SHORT_SHA=${FULL_SHA:0:7}" >> $GITHUB_OUTPUT + + - env: + AWS_REGION: us-east-1 + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ vars.AWS_ROLE }} + aws-region: ${{ env.AWS_REGION }} + + - id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 + with: + registry-type: public + + - env: + AWS_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + AWS_REGISTRY_ALIAS: k2y5k6e2 + AWS_REPO: release-chebi-update + IMG_TAG: ${{ steps.get-hash.outputs.SHORT_SHA }} + run: | + AWS_URI=$AWS_REGISTRY/$AWS_REGISTRY_ALIAS/$AWS_REPO + docker load --input /tmp/image.tar + docker tag tmp-tag $AWS_URI:latest + docker push $AWS_URI:latest + docker tag $AWS_URI:latest $AWS_URI:$IMG_TAG + docker push $AWS_URI:$IMG_TAG \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..034fab4 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,2 @@ +# 2.0.0 +Initial release of version 2.0.0 (refactoring of version 1 available [here](https://github.com/reactome/release-chebi-update)) \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..39dc52b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,39 @@ +ARG REPO_DIR=/opt/release-chebi-update + + +# ===== stage 1 ===== +FROM maven:3.9.6-eclipse-temurin-11-focal AS setup-env + +ARG REPO_DIR + +WORKDIR ${REPO_DIR} + +COPY . . + +SHELL ["/bin/bash", "-c"] + +# run lint if container started +ENTRYPOINT [] + +CMD mvn -B -q checkstyle:check | \ + grep -i --color=never '\.java\|failed to execute goal' > lint.log && \ + exit 1 || \ + exit 0 + + +# ===== stage 2 ===== +FROM setup-env AS build-jar + +RUN mvn clean compile assembly:single + + +# ===== stage 3 ===== +FROM eclipse-temurin:11-jre-focal + +ARG REPO_DIR + +ARG JAR_FILE=target/chebi-update-jar-with-dependencies.jar + +WORKDIR ${REPO_DIR} + +COPY --from=build-jar ${REPO_DIR}/${JAR_FILE} ./target/ \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..de795f2 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,107 @@ +// This Jenkinsfile is used by Jenkins to run the 'ChEBI Update' step of Reactome's release. +// This step synchronizes Reactome's database with ChEBI. + +import org.reactome.release.jenkins.utilities.Utilities + +// Shared library maintained at 'release-jenkins-utils' repository. +def utils = new Utilities() + +pipeline { + agent any + + environment { + ECR_URL = 'public.ecr.aws/reactome/release-chebi-update' + CONT_NAME = 'chebi_container' + CONT_ROOT = '/opt/release-chebi-update' + } + + stages { + // This stage checks that an upstream step, GO Update, was run successfully. + stage('Check GO Update build succeeded'){ + steps{ + script{ + utils.checkUpstreamBuildsSucceeded("ConfirmReleaseConfigs") + } + } + } + + // This stage makes the config/credentials file + stage('Setup: Get config/credentials'){ + steps{ + script{ + withCredentials([file(credentialsId: 'Config', variable: 'ConfigFile')]){ + sh "mkdir -p config" + sh "sudo cp $ConfigFile config/auth.properties" + sh "sudo chown jenkins:jenkins config/ -R" + } + } + } + } + + // This stage pulls the docker image and removes old containers + stage('Setup: Pull and clean docker environment'){ + steps{ + sh "docker pull ${ECR_URL}:latest" + sh """ + if docker ps -a --format '{{.Names}}' | grep -Eq '${CONT_NAME}'; then + docker rm -f ${CONT_NAME} + fi + """ + } + } + + // This stage executes the ChEBI Update jar file via docker. + stage('Main: ChEBI Update'){ + steps{ + sh """\ + docker run -v \$(pwd)/config:${CONT_ROOT}/config --net=host --name ${CONT_NAME} \\ + ${ECR_URL}:latest \\ + /bin/bash -c 'java -Xmx${env.JAVA_MEM_MAX}m -jar target/chebi-update-jar-with-dependencies.jar config/auth.properties' + """ + } + } + + // This stage backs up the gk_central database after modification. + stage('Post: Backup gk_central after modifications'){ + steps{ + script{ + withCredentials([usernamePassword(credentialsId: 'mySQLCuratorUsernamePassword', passwordVariable: 'pass', usernameVariable: 'user')]){ + utils.takeDatabaseDumpAndGzip("${env.GK_CENTRAL_DB}", "chebi_update", "after", "${env.CURATOR_SERVER}") + } + } + } + } + + // This stage archives the report files generated by ChEBI Update and sends them in an email to the default recipients list. + stage('Post: Email ChEBI Update Reports'){ + steps{ + script{ + def releaseVersion = utils.getReleaseVersion() + def chebiUpdateReportsFile = "chebi-update-v${releaseVersion}-reports.tgz" + + sh "mkdir -p reports" + sh "docker cp ${CONT_NAME}:${CONT_ROOT}/reports/. reports/" + sh "tar zcf ${chebiUpdateReportsFile} reports/" + + def emailSubject = "ChEBI Update Reports for v${releaseVersion}" + def emailBody = "Hello,\n\nThis is an automated message from Jenkins regarding an update for ${releaseVersion}. The ChEBI Update step has completed. Please review the reports attached to this email. If they look correct, these reports need to be uploaded to the Reactome Drive at Reactome>Release>Release QA>${releaseVersion}_QA>V${releaseVersion}_QA_ChEBI_Update_Reports. The URL to the new V${releaseVersion}_QA_ChEBI_Update_Reports folder also needs to be updated at https://devwiki.reactome.org/index.php/Reports_Archive under 'ChEBI Update Reports'. Please add the older ChEBI report URL to the 'Archived reports' section of the page. If they don't look correct, please email the developer running Release. \n\nThanks!" + utils.sendEmailWithAttachment("${emailSubject}", "${emailBody}", "${chebiUpdateReportsFile}") + } + } + } + + // All databases, logs, and data files generated by this step are compressed before moving them to the Reactome S3 bucket. All files are then deleted. + stage('Post: Archive Outputs'){ + steps{ + script{ + def releaseVersion = utils.getReleaseVersion() + def dataFiles = ["chebi-update-v${releaseVersion}-reports.tgz"] + // ChEBI Update log files are already in a folder called 'logs', so an empty list is passed. + def logFiles = [] + def foldersToDelete = [] + utils.cleanUpAndArchiveBuildFiles("chebi_update", dataFiles, logFiles, foldersToDelete) + } + } + } + } +} \ No newline at end of file diff --git a/checkstyle.xml b/checkstyle.xml new file mode 100644 index 0000000..03e2442 --- /dev/null +++ b/checkstyle.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file