diff --git a/.github/workflows/build-runner.yml b/.github/workflows/build-runner.yml deleted file mode 100644 index ea0f952..0000000 --- a/.github/workflows/build-runner.yml +++ /dev/null @@ -1,153 +0,0 @@ -name: Build web-tools Images - -on: - push: - branches: - - master - paths: - - 'openjdk*/*' - - 'node_version.env' - - '.github/workflows/build-runner.yml' - -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - jdk_version: [8, 11, 17, 21] - node_version: [18, 20, 22] - fail-fast: false - - steps: - - uses: actions/checkout@v4 - - - name: Docker login - env: - DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }} - DOCKER_HUB_PASSWORD: ${{ secrets.DOCKER_HUB_PASSWORD }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - echo $DOCKER_HUB_PASSWORD | docker login --username $DOCKER_HUB_USERNAME --password-stdin - echo $GITHUB_TOKEN | docker login ghcr.io --username $GITHUB_ACTOR --password-stdin - - - name: Set Environment Variables - id: vars - run: | - JDK_DIR=openjdk${{ matrix.jdk_version }}-alpine - NODE_MAJOR_VERSION=${{ matrix.node_version }} - NODE_VERSION="$(awk -F '[=]' '/NODE_${{ matrix.node_version }}_VERSION/ {print $2}' node_version.env)" - if [[ -f ${JDK_DIR}/Dockerfile ]]; then - OPENJDK_VERSION="$(awk -F '[=]' '/ENV OPENJDK_VERSION/ {print $2}' ${JDK_DIR}/Dockerfile)" - echo $NODE_VERSION > ${JDK_DIR}/version.txt - echo $OPENJDK_VERSION > ${JDK_DIR}/openjdk_version.txt - else - NODE_VERSION=$(cat ${JDK_DIR}/version.txt) - OPENJDK_VERSION=$(cat ${JDK_DIR}/openjdk_version.txt) - fi - echo "JDK_DIR=${JDK_DIR}" >> $GITHUB_ENV - echo "NODE_VERSION=${NODE_VERSION}" >> $GITHUB_ENV - echo "OPENJDK_VERSION=${OPENJDK_VERSION}" >> $GITHUB_ENV - echo "NODE_MAJOR_VERSION=${NODE_MAJOR_VERSION}" >> $GITHUB_ENV - - - name: Build Docker Image - run: | - IMAGE_NAME=ringcentral/web-tools - sed -i "s/\$NODE_VERSION/$NODE_VERSION/g" ${JDK_DIR}/Dockerfile - docker build --tag ${IMAGE_NAME} --file ${JDK_DIR}/Dockerfile . - - - name: Tag and Push Docker Images - run: | - IMAGE_NAME=ringcentral/web-tools - GH_DOCKER_PKG_IMAGE_NAME=ghcr.io/ringcentral-docker/web-tools/web-tools - - docker tag "${IMAGE_NAME}" "${IMAGE_NAME}:node${NODE_MAJOR_VERSION}-openjdk${OPENJDK_VERSION}-alpine" - docker push "${IMAGE_NAME}:node${NODE_MAJOR_VERSION}-openjdk${OPENJDK_VERSION}-alpine" - docker tag "${IMAGE_NAME}" "${GH_DOCKER_PKG_IMAGE_NAME}:node${NODE_MAJOR_VERSION}-openjdk${OPENJDK_VERSION}-alpine" - docker push "${GH_DOCKER_PKG_IMAGE_NAME}:node${NODE_MAJOR_VERSION}-openjdk${OPENJDK_VERSION}-alpine" - - if [ "${{ matrix.jdk_version }}" -eq 21 ]; then - docker tag "${IMAGE_NAME}" "${IMAGE_NAME}:${NODE_VERSION}-alpine" - docker tag "${IMAGE_NAME}" "${IMAGE_NAME}:${NODE_MAJOR_VERSION}-alpine" - docker push "${IMAGE_NAME}:${NODE_VERSION}-alpine" - docker push "${IMAGE_NAME}:${NODE_MAJOR_VERSION}-alpine" - - docker tag "${IMAGE_NAME}" "${GH_DOCKER_PKG_IMAGE_NAME}:${NODE_VERSION}-alpine" - docker tag "${IMAGE_NAME}" "${GH_DOCKER_PKG_IMAGE_NAME}:${NODE_MAJOR_VERSION}-alpine" - docker push "${GH_DOCKER_PKG_IMAGE_NAME}:${NODE_VERSION}-alpine" - docker push "${GH_DOCKER_PKG_IMAGE_NAME}:${NODE_MAJOR_VERSION}-alpine" - - if [ "${{ matrix.node_version }}" -eq 22 ]; then - docker tag "${IMAGE_NAME}" "${IMAGE_NAME}:latest" - docker push "${IMAGE_NAME}:latest" - docker tag "${IMAGE_NAME}" "${GH_DOCKER_PKG_IMAGE_NAME}:latest" - docker push "${GH_DOCKER_PKG_IMAGE_NAME}:latest" - fi - fi - - - name: Generate README Update - run: | - IMAGE_NAME=ringcentral/web-tools - GH_DOCKER_PKG_IMAGE_NAME=ghcr.io/ringcentral-docker/web-tools/web-tools - if [ "${{ matrix.node_version }}" -eq 22 ]; then - NEW_ENTRY="| JDK${{ matrix.jdk_version }} | ${NODE_DIR} | \`${IMAGE_NAME}:node${NODE_MAJOR_VERSION}-openjdk${OPENJDK_VERSION}-alpine\` | \`${GH_DOCKER_PKG_IMAGE_NAME}:node${NODE_MAJOR_VERSION}-openjdk${OPENJDK_VERSION}-alpine\` |" - echo "${NEW_ENTRY}" > readme_updates_${{ matrix.jdk_version }}.txt - fi - - - name: Upload README Update - uses: actions/upload-artifact@v4 - with: - name: readme-updates-${{ matrix.jdk_version }} - path: readme_updates_${{ matrix.jdk_version }}.txt - - update-readme: - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Download README Updates - uses: actions/download-artifact@v4 - with: - name: readme-updates-8 - path: ./readme-updates - - name: Download README Updates - uses: actions/download-artifact@v4 - with: - name: readme-updates-11 - path: ./readme-updates - - name: Download README Updates - uses: actions/download-artifact@v4 - with: - name: readme-updates-17 - path: ./readme-updates - - name: Download README Updates - uses: actions/download-artifact@v4 - with: - name: readme-updates-21 - path: ./readme-updates - - - name: Initialize README - run: | - echo "| JDK Version | Version | Docker Hub | GitHub Package |" > README.md - echo "|-------------|---------|------------|----------------|" >> README.md - - name: Update README - run: | - for file in ./readme-updates/readme_updates_*.txt; do - while IFS= read -r line; do - JDK_VERSION=$(echo $line | cut -d' ' -f2) - if grep -q "JDK${JDK_VERSION}" README.md; then - sed -i "/JDK${JDK_VERSION}/c\\$line" README.md - else - echo "$line" >> README.md - fi - done < "$file" - done - - - name: Commit README Update - run: | - git config --global user.name 'john.lin' - git config --global user.email 'john.lin@ringcentral.com' - git add README.md - git commit -m "Update README with Docker image info" - git push - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..02984cd --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,218 @@ +name: Build Web Tools Images + +on: + push: + branches: + - master + paths: + - 'Dockerfile' + - 'versions/**' + - 'scripts/**' + - '.github/workflows/build.yml' + pull_request: + paths: + - 'Dockerfile' + - 'versions/**' + - 'scripts/**' + - '.github/workflows/build.yml' + workflow_dispatch: + inputs: + version: + description: 'Specific version to build (e.g., node22-jdk21), or "all" for all versions' + required: false + default: 'all' + +env: + DOCKER_HUB_IMAGE: ringcentral/web-tools + GHCR_IMAGE: ghcr.io/ringcentral-docker/web-tools + +jobs: + # ============================================================================= + # Generate build matrix from versions.json + # ============================================================================= + prepare: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - uses: actions/checkout@v4 + + - name: Generate build matrix + id: set-matrix + run: | + if [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ github.event.inputs.version }}" != "all" ]]; then + MATRIX=$(jq -c --arg v "${{ github.event.inputs.version }}" \ + '{include: [.versions[] | select(.name == $v)]}' versions/versions.json) + else + MATRIX=$(jq -c '{include: .versions}' versions/versions.json) + fi + echo "matrix=${MATRIX}" >> $GITHUB_OUTPUT + + # ============================================================================= + # Build and push Docker images + # ============================================================================= + build: + needs: prepare + runs-on: ubuntu-latest + strategy: + matrix: ${{ fromJson(needs.prepare.outputs.matrix) }} + fail-fast: false + + steps: + - uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_PASSWORD }} + + - name: Login to GitHub Container Registry + if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Generate Docker tags + id: meta + run: | + NAME="${{ matrix.name }}" + NODE_VERSION="${{ matrix.node_version }}" + NODE_MAJOR="${{ matrix.node_major }}" + JDK_VERSION="${{ matrix.jdk_version }}" + IS_LATEST="${{ matrix.is_latest }}" + + TAGS="" + for REGISTRY in "${{ env.DOCKER_HUB_IMAGE }}" "${{ env.GHCR_IMAGE }}"; do + # Primary tag: node22-jdk21 + TAGS="${TAGS}${REGISTRY}:${NAME}," + # Version tag: node22.11.0-jdk21 + TAGS="${TAGS}${REGISTRY}:node${NODE_VERSION}-jdk${JDK_VERSION}," + + # Latest tag for node22-jdk21 + if [[ "${IS_LATEST}" == "true" ]]; then + TAGS="${TAGS}${REGISTRY}:latest," + fi + done + + echo "tags=${TAGS%,}" >> $GITHUB_OUTPUT + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + platforms: linux/amd64,linux/arm64 + push: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + build-args: | + BASE_IMAGE_TAG=${{ matrix.base_image_tag }} + GRADLE_VERSION=${{ matrix.gradle_version }} + SONAR_VERSION=${{ matrix.sonar_version }} + CX_FLOW_VERSION=${{ matrix.cx_flow_version }} + CX_FLOW_JAR=${{ matrix.cx_flow_jar }} + SCA_RESOLVER_VERSION=${{ matrix.sca_resolver_version }} + cache-from: type=gha,scope=${{ matrix.name }} + cache-to: type=gha,mode=max,scope=${{ matrix.name }} + + # ============================================================================= + # Update README - Generate directly from versions.json (master only) + # ============================================================================= + update-readme: + needs: build + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + + - name: Generate README from versions.json + run: | + cat > README.md << 'HEADER' + # Web Tools Docker Images + + Multi-platform Docker images with Node.js, Java, Maven, Gradle, and development tools. + + ## Supported Platforms + + - linux/amd64 + - linux/arm64 + + ## Available Images + + | Name | Node | JDK | Gradle | Docker Hub | GitHub Package | + |------|------|-----|--------|------------|----------------| + HEADER + + # Generate table rows from versions.json using jq + jq -r --arg hub "${{ env.DOCKER_HUB_IMAGE }}" \ + --arg ghcr "${{ env.GHCR_IMAGE }}" \ + '.versions[] | + "| \(.name) | \(.node_version) | \(.jdk_version) | \(.gradle_version) | `\($hub):\(.name)` | `\($ghcr):\(.name)` |" + ' versions/versions.json >> README.md + + cat >> README.md << 'FOOTER' + + ## Included Tools + + - **Node.js** - JavaScript runtime + - **Maven** - Java build tool + - **Gradle** - Build automation + - **Chromium** - Headless browser for Puppeteer + - **Sonar Scanner** - Code quality analysis + - **Checkmarx** - Security scanning (cx-flow, sca-resolver) + - **Git, Mercurial** - Version control + - **Python3** - For npm native modules + + ## Usage + + ```bash + # Pull from Docker Hub + docker pull ringcentral/web-tools:node22-jdk21 + + # Pull from GitHub Container Registry + docker pull ghcr.io/ringcentral-docker/web-tools:node22-jdk21 + + # Run + docker run -it ringcentral/web-tools:node22-jdk21 bash + ``` + + ## Build Locally + + ```bash + docker build \ + --build-arg BASE_IMAGE_TAG=22.11.0-jdk21 \ + --build-arg GRADLE_VERSION=8.5 \ + --build-arg SONAR_VERSION=4.8.0.2856 \ + --build-arg CX_FLOW_VERSION=1.7.11 \ + --build-arg CX_FLOW_JAR=cx-flow.jar \ + --build-arg SCA_RESOLVER_VERSION=2.12.36 \ + -t my-web-tools:node22-jdk21 . + ``` + + ## License + + MIT License + FOOTER + + - name: Commit README + run: | + git config --global user.name 'github-actions[bot]' + git config --global user.email 'github-actions[bot]@users.noreply.github.com' + git add README.md + if git diff --staged --quiet; then + echo "No changes to commit" + else + git commit -m "docs: update README with Docker image info" + git push + fi diff --git a/.gitignore b/.gitignore index c188842..b085086 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .idea -readme-updates \ No newline at end of file +readme-updates +.spec-workflow \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..64e8938 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,66 @@ +# Parameterized Web Tools Dockerfile +# +# Build example: +# docker build \ +# --build-arg BASE_IMAGE_TAG=22.11.0-jdk21 \ +# --build-arg GRADLE_VERSION=8.5 \ +# --build-arg SONAR_VERSION=4.8.0.2856 \ +# --build-arg CX_FLOW_VERSION=1.7.11 \ +# --build-arg CX_FLOW_JAR=cx-flow.jar \ +# --build-arg SCA_RESOLVER_VERSION=2.12.36 \ +# -t ringcentral/web-tools:node22-jdk21 . + +ARG BASE_IMAGE_TAG=22.11.0-jdk21 + +FROM ghcr.io/ringcentral-docker/node:${BASE_IMAGE_TAG} + +LABEL maintainer="john.lin@ringcentral.com" + +# Build arguments +ARG GRADLE_VERSION=8.5 +ARG SONAR_VERSION=4.8.0.2856 +ARG CX_FLOW_VERSION=1.7.11 +ARG CX_FLOW_JAR=cx-flow.jar +ARG SCA_RESOLVER_VERSION=2.12.36 + +# Environment variables +ENV GRADLE_VERSION=${GRADLE_VERSION} \ + SONAR_VERSION=${SONAR_VERSION} \ + CX_FLOW_VERSION=${CX_FLOW_VERSION} \ + SCA_RESOLVER_VERSION=${SCA_RESOLVER_VERSION} + +# Copy installation scripts +COPY scripts/ /tmp/scripts/ +RUN chmod +x /tmp/scripts/*.sh + +# Install base tools +RUN /tmp/scripts/install-base.sh + +# Install Gradle +RUN /tmp/scripts/install-gradle.sh + +# Install Puppeteer/Chromium dependencies +RUN /tmp/scripts/install-chromium.sh + +# Install Sonar Scanner +RUN /tmp/scripts/install-sonar.sh + +# Install Checkmarx tools +RUN /tmp/scripts/install-checkmarx.sh ${CX_FLOW_JAR} + +# Cleanup +RUN rm -rf /tmp/scripts /var/lib/apt/lists/* /tmp/* /var/tmp/* + +# Final version summary +RUN echo "=== Final Version Summary ===" \ + && java -version \ + && javac -version \ + && mvn -version \ + && gradle --version \ + && node --version \ + && npm version \ + && yarn --version \ + && python3 --version \ + && git --version \ + && (command -v chromium && chromium --version --no-sandbox || echo "chromium: not installed") \ + && (command -v sonar-scanner && sonar-scanner --version || echo "sonar-scanner: not installed") diff --git a/node_version.env b/node_version.env deleted file mode 100644 index e639f21..0000000 --- a/node_version.env +++ /dev/null @@ -1,3 +0,0 @@ -NODE_18_VERSION=18.20.8 -NODE_20_VERSION=20.19.3 -NODE_22_VERSION=22.17.0 \ No newline at end of file diff --git a/openjdk11-alpine/Dockerfile b/openjdk11-alpine/Dockerfile deleted file mode 100644 index 4d21104..0000000 --- a/openjdk11-alpine/Dockerfile +++ /dev/null @@ -1,104 +0,0 @@ -FROM public.ecr.aws/docker/library/node:$NODE_VERSION-alpine - -# OpenJDK -ENV JAVA_HOME="/usr/lib/jvm/default-jvm" -ENV OPENJDK_VERSION=11 - -RUN apk update \ - && apk add --no-cache openjdk${OPENJDK_VERSION} \ - && rm -rf /var/cache/apk/* - -# Has to be set explictly to find binaries -ENV PATH="$PATH:${JAVA_HOME}/bin" - -# Required libraries -RUN apk add --no-cache git unzip zip curl jq yq && \ - rm -rf /var/cache/apk/* - -# Maven -RUN apk update \ - && apk add --no-cache maven \ - && rm -rf /var/cache/apk/* - -# Gradle -WORKDIR /opt - -ENV GRADLE_VERSION=7.6 - -RUN curl -sL https://downloads.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip > gradle.zip && \ - unzip gradle.zip && \ - rm gradle.zip && \ - rm -rf /var/cache/apk/* - -ENV PATH="$PATH:/opt/gradle-${GRADLE_VERSION}/bin" - -# Mercurial -RUN apk update \ - && apk add --no-cache mercurial \ - && rm -rf /var/cache/apk/* - -# rng-tools for FED Project -RUN apk update \ - && apk add --no-cache rng-tools \ - && rm -rf /var/cache/apk/* - -# bash for MAA project -RUN apk update \ - && apk add --no-cache bash openssh \ - && rm -rf /var/cache/apk/* - -# Tell Puppeteer to skip installing Chrome. We'll be using the installed package. -ENV CHROME_BIN=/usr/bin/chromium-browser \ - PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser \ - PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true - -# Puppeteer -# https://github.com/adrianchia/docker-node-puppeteer/blob/master/12/alpine/Dockerfile -# https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md#running-on-alpine - -RUN apk update \ - && apk add --no-cache \ - chromium \ - nss \ - freetype \ - freetype-dev \ - harfbuzz \ - ca-certificates \ - ttf-freefont \ - && rm -rf /var/cache/apk/* - -# Sonar -# https://community.sonarsource.com/t/installing-sonar-scanner-in-alpine-linux-docker/7010 - -RUN curl -sL https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.2.2472-linux.zip -o sonar.zip && \ - unzip -qq sonar.zip && \ - rm sonar.zip && \ - ln -s /opt/sonar-scanner-4.6.2.2472-linux/bin/sonar-scanner /usr/local/bin/sonar-scanner && \ - sed -i 's/use_embedded_jre=true/use_embedded_jre=false/g' /opt/sonar-scanner-4.6.2.2472-linux/bin/sonar-scanner && \ - sonar-scanner --version - -# Python (needed for NPM install Gyp) - -RUN apk add --no-cache --virtual .gyp python3 make g++ - -# Checkmarx tools for Java 11 -ENV CX_FLOW_VERSION=1.6.46 SCA_RESOLVER_VERSION=2.12.36 - -RUN mkdir cx-flow && \ - curl -sL https://github.com/checkmarx-ltd/cx-flow/releases/download/${CX_FLOW_VERSION}/cx-flow-${CX_FLOW_VERSION}-java11.jar > ./cx-flow/cx-flow.jar - -RUN mkdir sca-resolver && \ - curl -sL "https://sca-downloads.s3.amazonaws.com/cli/${SCA_RESOLVER_VERSION}/ScaResolver-musl64.tar.gz" > ./sca-resolver/ScaResolver.tar.gz && \ - tar -vxzf ./sca-resolver/ScaResolver.tar.gz -C ./sca-resolver && \ - rm ./sca-resolver/ScaResolver.tar.gz - -#============== -# Show version -#============== -RUN java -version \ - && javac -version \ - && mvn -version \ - && node --version \ - && npm version \ - && yarn --version \ - && python3 --version diff --git a/openjdk17-alpine/Dockerfile b/openjdk17-alpine/Dockerfile deleted file mode 100644 index 732a8ee..0000000 --- a/openjdk17-alpine/Dockerfile +++ /dev/null @@ -1,104 +0,0 @@ -FROM public.ecr.aws/docker/library/node:$NODE_VERSION-alpine - -# OpenJDK -ENV JAVA_HOME="/usr/lib/jvm/default-jvm" -ENV OPENJDK_VERSION=17 - -RUN apk update \ - && apk add --no-cache openjdk${OPENJDK_VERSION} \ - && rm -rf /var/cache/apk/* - -# Has to be set explictly to find binaries -ENV PATH="$PATH:${JAVA_HOME}/bin" - -# Required libraries -RUN apk add --no-cache git unzip zip curl jq yq && \ - rm -rf /var/cache/apk/* - -# Maven -RUN apk update \ - && apk add --no-cache maven \ - && rm -rf /var/cache/apk/* - -# Gradle -WORKDIR /opt - -ENV GRADLE_VERSION=8.5 - -RUN curl -sL https://downloads.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip > gradle.zip && \ - unzip gradle.zip && \ - rm gradle.zip && \ - rm -rf /var/cache/apk/* - -ENV PATH="$PATH:/opt/gradle-${GRADLE_VERSION}/bin" - -# Mercurial -RUN apk update \ - && apk add --no-cache mercurial \ - && rm -rf /var/cache/apk/* - -# rng-tools for FED Project -RUN apk update \ - && apk add --no-cache rng-tools \ - && rm -rf /var/cache/apk/* - -# bash for MAA project -RUN apk update \ - && apk add --no-cache bash openssh \ - && rm -rf /var/cache/apk/* - -# Tell Puppeteer to skip installing Chrome. We'll be using the installed package. -ENV CHROME_BIN=/usr/bin/chromium-browser \ - PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser \ - PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true - -# Puppeteer -# https://github.com/adrianchia/docker-node-puppeteer/blob/master/12/alpine/Dockerfile -# https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md#running-on-alpine - -RUN apk update \ - && apk add --no-cache \ - chromium \ - nss \ - freetype \ - freetype-dev \ - harfbuzz \ - ca-certificates \ - ttf-freefont \ - && rm -rf /var/cache/apk/* - -# Sonar -# https://community.sonarsource.com/t/installing-sonar-scanner-in-alpine-linux-docker/7010 - -RUN curl -sL https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.8.0.2856-linux.zip -o sonar.zip && \ - unzip -qq sonar.zip && \ - rm sonar.zip && \ - ln -s /opt/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner /usr/local/bin/sonar-scanner && \ - sed -i 's/use_embedded_jre=true/use_embedded_jre=false/g' /opt/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner && \ - sonar-scanner --version - -# Python (needed for NPM install Gyp) - -RUN apk add --no-cache --virtual .gyp python3 make g++ - -# Checkmarx tools for Java 17+ -ENV CX_FLOW_VERSION=1.7.11 SCA_RESOLVER_VERSION=2.12.36 - -RUN mkdir cx-flow && \ - curl -sL https://github.com/checkmarx-ltd/cx-flow/releases/download/${CX_FLOW_VERSION}/cx-flow-${CX_FLOW_VERSION}.jar > ./cx-flow/cx-flow.jar - -RUN mkdir sca-resolver && \ - curl -sL "https://sca-downloads.s3.amazonaws.com/cli/${SCA_RESOLVER_VERSION}/ScaResolver-musl64.tar.gz" > ./sca-resolver/ScaResolver.tar.gz && \ - tar -vxzf ./sca-resolver/ScaResolver.tar.gz -C ./sca-resolver && \ - rm ./sca-resolver/ScaResolver.tar.gz - -#============== -# Show version -#============== -RUN java -version \ - && javac -version \ - && mvn -version \ - && node --version \ - && npm version \ - && yarn --version \ - && python3 --version diff --git a/openjdk21-alpine/Dockerfile b/openjdk21-alpine/Dockerfile deleted file mode 100644 index b4e077b..0000000 --- a/openjdk21-alpine/Dockerfile +++ /dev/null @@ -1,104 +0,0 @@ -FROM public.ecr.aws/docker/library/node:$NODE_VERSION-alpine - -# OpenJDK -ENV JAVA_HOME="/usr/lib/jvm/default-jvm" -ENV OPENJDK_VERSION=21 - -RUN apk update \ - && apk add --no-cache openjdk${OPENJDK_VERSION} \ - && rm -rf /var/cache/apk/* - -# Has to be set explictly to find binaries -ENV PATH="$PATH:${JAVA_HOME}/bin" - -# Required libraries -RUN apk add --no-cache git unzip zip curl jq yq && \ - rm -rf /var/cache/apk/* - -# Maven -RUN apk update \ - && apk add --no-cache maven \ - && rm -rf /var/cache/apk/* - -# Gradle -WORKDIR /opt - -ENV GRADLE_VERSION=8.5 - -RUN curl -sL https://downloads.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip > gradle.zip && \ - unzip gradle.zip && \ - rm gradle.zip && \ - rm -rf /var/cache/apk/* - -ENV PATH="$PATH:/opt/gradle-${GRADLE_VERSION}/bin" - -# Mercurial -RUN apk update \ - && apk add --no-cache mercurial \ - && rm -rf /var/cache/apk/* - -# rng-tools for FED Project -RUN apk update \ - && apk add --no-cache rng-tools \ - && rm -rf /var/cache/apk/* - -# bash for MAA project -RUN apk update \ - && apk add --no-cache bash openssh \ - && rm -rf /var/cache/apk/* - -# Tell Puppeteer to skip installing Chrome. We'll be using the installed package. -ENV CHROME_BIN=/usr/bin/chromium-browser \ - PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser \ - PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true - -# Puppeteer -# https://github.com/adrianchia/docker-node-puppeteer/blob/master/12/alpine/Dockerfile -# https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md#running-on-alpine - -RUN apk update \ - && apk add --no-cache \ - chromium \ - nss \ - freetype \ - freetype-dev \ - harfbuzz \ - ca-certificates \ - ttf-freefont \ - && rm -rf /var/cache/apk/* - -# Sonar -# https://community.sonarsource.com/t/installing-sonar-scanner-in-alpine-linux-docker/7010 - -RUN curl -sL https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.8.0.2856-linux.zip -o sonar.zip && \ - unzip -qq sonar.zip && \ - rm sonar.zip && \ - ln -s /opt/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner /usr/local/bin/sonar-scanner && \ - sed -i 's/use_embedded_jre=true/use_embedded_jre=false/g' /opt/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner && \ - sonar-scanner --version - -# Python (needed for NPM install Gyp) - -RUN apk add --no-cache --virtual .gyp python3 make g++ - -# Checkmarx tools for Java 17+ -ENV CX_FLOW_VERSION=1.7.11 SCA_RESOLVER_VERSION=2.12.36 - -RUN mkdir cx-flow && \ - curl -sL https://github.com/checkmarx-ltd/cx-flow/releases/download/${CX_FLOW_VERSION}/cx-flow-${CX_FLOW_VERSION}.jar > ./cx-flow/cx-flow.jar - -RUN mkdir sca-resolver && \ - curl -sL "https://sca-downloads.s3.amazonaws.com/cli/${SCA_RESOLVER_VERSION}/ScaResolver-musl64.tar.gz" > ./sca-resolver/ScaResolver.tar.gz && \ - tar -vxzf ./sca-resolver/ScaResolver.tar.gz -C ./sca-resolver && \ - rm ./sca-resolver/ScaResolver.tar.gz - -#============== -# Show version -#============== -RUN java -version \ - && javac -version \ - && mvn -version \ - && node --version \ - && npm version \ - && yarn --version \ - && python3 --version diff --git a/openjdk8-alpine/Dockerfile b/openjdk8-alpine/Dockerfile deleted file mode 100644 index c58867d..0000000 --- a/openjdk8-alpine/Dockerfile +++ /dev/null @@ -1,104 +0,0 @@ -FROM public.ecr.aws/docker/library/node:$NODE_VERSION-alpine - -# OpenJDK -ENV JAVA_HOME="/usr/lib/jvm/default-jvm" -ENV OPENJDK_VERSION=8 - -RUN apk update \ - && apk add --no-cache openjdk${OPENJDK_VERSION} \ - && rm -rf /var/cache/apk/* - -# Has to be set explictly to find binaries -ENV PATH="$PATH:${JAVA_HOME}/bin" - -# Required libraries -RUN apk add --no-cache git unzip zip curl jq yq && \ - rm -rf /var/cache/apk/* - -# Maven -RUN apk update \ - && apk add --no-cache maven \ - && rm -rf /var/cache/apk/* - -# Gradle -WORKDIR /opt - -ENV GRADLE_VERSION=7.6 - -RUN curl -sL https://downloads.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip > gradle.zip && \ - unzip gradle.zip && \ - rm gradle.zip && \ - rm -rf /var/cache/apk/* - -ENV PATH="$PATH:/opt/gradle-${GRADLE_VERSION}/bin" - -# Mercurial -RUN apk update \ - && apk add --no-cache mercurial \ - && rm -rf /var/cache/apk/* - -# rng-tools for FED Project -RUN apk update \ - && apk add --no-cache rng-tools \ - && rm -rf /var/cache/apk/* - -# bash for MAA project -RUN apk update \ - && apk add --no-cache bash openssh \ - && rm -rf /var/cache/apk/* - -# Tell Puppeteer to skip installing Chrome. We'll be using the installed package. -ENV CHROME_BIN=/usr/bin/chromium-browser \ - PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser \ - PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true - -# Puppeteer -# https://github.com/adrianchia/docker-node-puppeteer/blob/master/12/alpine/Dockerfile -# https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md#running-on-alpine - -RUN apk update \ - && apk add --no-cache \ - chromium \ - nss \ - freetype \ - freetype-dev \ - harfbuzz \ - ca-certificates \ - ttf-freefont \ - && rm -rf /var/cache/apk/* - -# Sonar -# https://community.sonarsource.com/t/installing-sonar-scanner-in-alpine-linux-docker/7010 - -RUN curl -sL https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.2.2472-linux.zip -o sonar.zip && \ - unzip -qq sonar.zip && \ - rm sonar.zip && \ - ln -s /opt/sonar-scanner-4.6.2.2472-linux/bin/sonar-scanner /usr/local/bin/sonar-scanner && \ - sed -i 's/use_embedded_jre=true/use_embedded_jre=false/g' /opt/sonar-scanner-4.6.2.2472-linux/bin/sonar-scanner && \ - sonar-scanner --version - -# Python (needed for NPM install Gyp) - -RUN apk add --no-cache --virtual .gyp python3 make g++ - -# Checkmarx tools for Java 8 -ENV CX_FLOW_VERSION=1.6.46 SCA_RESOLVER_VERSION=2.12.36 - -RUN mkdir cx-flow && \ - curl -sL https://github.com/checkmarx-ltd/cx-flow/releases/download/${CX_FLOW_VERSION}/cx-flow-${CX_FLOW_VERSION}.jar > ./cx-flow/cx-flow.jar - -RUN mkdir sca-resolver && \ - curl -sL "https://sca-downloads.s3.amazonaws.com/cli/${SCA_RESOLVER_VERSION}/ScaResolver-musl64.tar.gz" > ./sca-resolver/ScaResolver.tar.gz && \ - tar -vxzf ./sca-resolver/ScaResolver.tar.gz -C ./sca-resolver && \ - rm ./sca-resolver/ScaResolver.tar.gz - -#============== -# Show version -#============== -RUN java -version \ - && javac -version \ - && mvn -version \ - && node --version \ - && npm version \ - && yarn --version \ - && python3 --version diff --git a/scripts/install-base.sh b/scripts/install-base.sh new file mode 100644 index 0000000..ba3e25b --- /dev/null +++ b/scripts/install-base.sh @@ -0,0 +1,43 @@ +#!/bin/bash +set -e + +echo "Installing base tools..." + +apt-get update && apt-get install -y --no-install-recommends \ + git \ + unzip \ + zip \ + curl \ + wget \ + jq \ + bash \ + openssh-client \ + mercurial \ + rng-tools \ + python3 \ + python3-pip \ + make \ + g++ \ + ca-certificates \ + gnupg \ + && rm -rf /var/lib/apt/lists/* + +# Install yq +YQ_VERSION="v4.50.1" +ARCH=$(dpkg --print-architecture) +case "${ARCH}" in + amd64) YQ_ARCH="amd64" ;; + arm64) YQ_ARCH="arm64" ;; + *) echo "Unsupported architecture: ${ARCH}" && exit 1 ;; +esac +curl -sL "https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_${YQ_ARCH}" -o /usr/local/bin/yq \ + && chmod +x /usr/local/bin/yq + +# Verify installations +echo "=== Verifying base tools ===" +git --version +curl --version | head -1 +jq --version +yq --version +python3 --version +echo "Base tools installed successfully." diff --git a/scripts/install-checkmarx.sh b/scripts/install-checkmarx.sh new file mode 100644 index 0000000..54259a4 --- /dev/null +++ b/scripts/install-checkmarx.sh @@ -0,0 +1,40 @@ +#!/bin/bash +set -e + +CX_FLOW_JAR=${1:-cx-flow.jar} + +echo "Installing Checkmarx tools..." +echo " CX_FLOW_VERSION: ${CX_FLOW_VERSION}" +echo " CX_FLOW_JAR: ${CX_FLOW_JAR}" +echo " SCA_RESOLVER_VERSION: ${SCA_RESOLVER_VERSION}" + +# Detect architecture +ARCH=$(dpkg --print-architecture) +case "${ARCH}" in + amd64) SCA_ARCH="linux64" ;; + arm64) SCA_ARCH="linux-arm64" ;; + *) echo "Unsupported architecture: ${ARCH}" && exit 1 ;; +esac + +echo " Architecture: ${ARCH} -> ${SCA_ARCH}" + +cd /opt + +# Install cx-flow (Java-based, architecture independent) +mkdir -p cx-flow +curl -sL "https://github.com/checkmarx-ltd/cx-flow/releases/download/${CX_FLOW_VERSION}/${CX_FLOW_JAR}" \ + -o ./cx-flow/cx-flow.jar + +# Install sca-resolver (architecture specific) +mkdir -p sca-resolver +curl -sL "https://sca-downloads.s3.amazonaws.com/cli/${SCA_RESOLVER_VERSION}/ScaResolver-${SCA_ARCH}.tar.gz" \ + -o ./sca-resolver/ScaResolver.tar.gz \ + && tar -xzf ./sca-resolver/ScaResolver.tar.gz -C ./sca-resolver \ + && rm ./sca-resolver/ScaResolver.tar.gz + +# Verify installation +echo "=== Verifying Checkmarx tools ===" +ls -la /opt/cx-flow/cx-flow.jar +ls -la /opt/sca-resolver/ + +echo "Checkmarx tools installed successfully." diff --git a/scripts/install-chromium.sh b/scripts/install-chromium.sh new file mode 100644 index 0000000..1bd58fb --- /dev/null +++ b/scripts/install-chromium.sh @@ -0,0 +1,72 @@ +#!/bin/bash +set -e + +echo "Installing Chromium and Puppeteer dependencies..." + +# Detect architecture +ARCH=$(dpkg --print-architecture) + +# Install common dependencies for Puppeteer +apt-get update && apt-get install -y --no-install-recommends \ + fonts-liberation \ + fonts-dejavu-core \ + libgbm1 \ + libnss3 \ + libatk1.0-0 \ + libatk-bridge2.0-0 \ + libcups2 \ + libdrm2 \ + libxkbcommon0 \ + libxcomposite1 \ + libxdamage1 \ + libxfixes3 \ + libxrandr2 \ + libpango-1.0-0 \ + libcairo2 \ + libasound2t64 \ + libxshmfence1 \ + libglu1-mesa \ + && rm -rf /var/lib/apt/lists/* + +if [[ "${ARCH}" == "amd64" ]]; then + echo "Downloading Chromium from official snapshots..." + + # Get latest version + CHROMIUM_VERSION=$(curl -s "https://www.googleapis.com/download/storage/v1/b/chromium-browser-snapshots/o/Linux_x64%2FLAST_CHANGE?alt=media") + echo " Latest version: ${CHROMIUM_VERSION}" + + # Download and extract + cd /opt + curl -sL "https://www.googleapis.com/download/storage/v1/b/chromium-browser-snapshots/o/Linux_x64%2F${CHROMIUM_VERSION}%2Fchrome-linux.zip?alt=media" -o chromium.zip + unzip -q chromium.zip + rm chromium.zip + + # Create symlink + ln -s /opt/chrome-linux/chrome /usr/local/bin/chromium + + CHROMIUM_BIN="/usr/local/bin/chromium" +else + echo "WARNING: Chromium official builds not available for ${ARCH}, skipping..." + echo " Puppeteer will need to download its own Chromium or use a custom executable." + + # Set empty path - Puppeteer will handle this + CHROMIUM_BIN="" +fi + +# Set Puppeteer environment variables +if [[ -n "${CHROMIUM_BIN}" ]]; then + echo "export CHROME_BIN=${CHROMIUM_BIN}" >> /etc/profile.d/chromium.sh + echo "export PUPPETEER_EXECUTABLE_PATH=${CHROMIUM_BIN}" >> /etc/profile.d/chromium.sh +fi +echo 'export PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true' >> /etc/profile.d/chromium.sh +chmod +x /etc/profile.d/chromium.sh + +# Verify installation +echo "=== Verifying Chromium ===" +if [[ -n "${CHROMIUM_BIN}" && -x "${CHROMIUM_BIN}" ]]; then + ${CHROMIUM_BIN} --version --no-sandbox +else + echo "Chromium not installed on this architecture (${ARCH})" +fi + +echo "Chromium installation completed." diff --git a/scripts/install-gradle.sh b/scripts/install-gradle.sh new file mode 100644 index 0000000..5f1784c --- /dev/null +++ b/scripts/install-gradle.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -e + +echo "Installing Gradle ${GRADLE_VERSION}..." + +cd /opt +curl -sL "https://downloads.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip" -o gradle.zip \ + && unzip -q gradle.zip \ + && rm gradle.zip \ + && ln -s /opt/gradle-${GRADLE_VERSION}/bin/gradle /usr/local/bin/gradle + +# Verify installation +echo "=== Verifying Gradle ===" +gradle --version + +echo "Gradle ${GRADLE_VERSION} installed successfully." diff --git a/scripts/install-sonar.sh b/scripts/install-sonar.sh new file mode 100644 index 0000000..8df2ebe --- /dev/null +++ b/scripts/install-sonar.sh @@ -0,0 +1,42 @@ +#!/bin/bash +set -e + +echo "Installing Sonar Scanner ${SONAR_VERSION}..." + +# Detect architecture +ARCH=$(dpkg --print-architecture) + +# Determine version major (e.g., 4.8.0.2856 -> 4) +VERSION_MAJOR=$(echo "${SONAR_VERSION}" | cut -d. -f1) + +# Sonar Scanner 5.x+ uses linux-x64/linux-aarch64, older versions use just "linux" +if [[ "${VERSION_MAJOR}" -ge 5 ]]; then + case "${ARCH}" in + amd64) SONAR_ARCH="linux-x64" ;; + arm64) SONAR_ARCH="linux-aarch64" ;; + *) echo "Unsupported architecture: ${ARCH}" && exit 1 ;; + esac +else + # Older versions (4.x) only support x64 with "linux" suffix + if [[ "${ARCH}" == "arm64" ]]; then + echo "WARNING: Sonar Scanner ${SONAR_VERSION} does not support arm64, skipping installation." + echo "=== Sonar Scanner skipped (no arm64 support) ===" + exit 0 + fi + SONAR_ARCH="linux" +fi + +echo " Architecture: ${ARCH} -> ${SONAR_ARCH}" + +cd /opt +curl -sL "https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_VERSION}-${SONAR_ARCH}.zip" -o sonar.zip \ + && unzip -q sonar.zip \ + && rm sonar.zip \ + && ln -s /opt/sonar-scanner-${SONAR_VERSION}-${SONAR_ARCH}/bin/sonar-scanner /usr/local/bin/sonar-scanner \ + && sed -i 's/use_embedded_jre=true/use_embedded_jre=false/g' /opt/sonar-scanner-${SONAR_VERSION}-${SONAR_ARCH}/bin/sonar-scanner + +# Verify installation +echo "=== Verifying Sonar Scanner ===" +sonar-scanner --version + +echo "Sonar Scanner ${SONAR_VERSION} installed successfully." diff --git a/versions/versions.json b/versions/versions.json new file mode 100644 index 0000000..3254f69 --- /dev/null +++ b/versions/versions.json @@ -0,0 +1,108 @@ +{ + "versions": [ + { + "name": "node20-jdk8", + "node_version": "20.18.0", + "node_major": "20", + "jdk_version": "8", + "base_image_tag": "20.18.0-jdk8", + "gradle_version": "7.6", + "sonar_version": "4.8.0.2856", + "cx_flow_version": "1.6.46", + "cx_flow_jar": "cx-flow.jar", + "sca_resolver_version": "2.12.36", + "is_latest": false + }, + { + "name": "node22-jdk8", + "node_version": "22.11.0", + "node_major": "22", + "jdk_version": "8", + "base_image_tag": "22.11.0-jdk8", + "gradle_version": "7.6", + "sonar_version": "4.8.0.2856", + "cx_flow_version": "1.6.46", + "cx_flow_jar": "cx-flow.jar", + "sca_resolver_version": "2.12.36", + "is_latest": false + }, + { + "name": "node20-jdk11", + "node_version": "20.18.0", + "node_major": "20", + "jdk_version": "11", + "base_image_tag": "20.18.0-jdk11", + "gradle_version": "7.6", + "sonar_version": "4.8.0.2856", + "cx_flow_version": "1.6.46", + "cx_flow_jar": "cx-flow-java11.jar", + "sca_resolver_version": "2.12.36", + "is_latest": false + }, + { + "name": "node22-jdk11", + "node_version": "22.11.0", + "node_major": "22", + "jdk_version": "11", + "base_image_tag": "22.11.0-jdk11", + "gradle_version": "7.6", + "sonar_version": "4.8.0.2856", + "cx_flow_version": "1.6.46", + "cx_flow_jar": "cx-flow-java11.jar", + "sca_resolver_version": "2.12.36", + "is_latest": false + }, + { + "name": "node20-jdk17", + "node_version": "20.18.0", + "node_major": "20", + "jdk_version": "17", + "base_image_tag": "20.18.0-jdk17", + "gradle_version": "8.5", + "sonar_version": "6.2.1.4610", + "cx_flow_version": "1.7.11", + "cx_flow_jar": "cx-flow.jar", + "sca_resolver_version": "2.12.36", + "is_latest": false + }, + { + "name": "node22-jdk17", + "node_version": "22.11.0", + "node_major": "22", + "jdk_version": "17", + "base_image_tag": "22.11.0-jdk17", + "gradle_version": "8.5", + "sonar_version": "6.2.1.4610", + "cx_flow_version": "1.7.11", + "cx_flow_jar": "cx-flow.jar", + "sca_resolver_version": "2.12.36", + "is_latest": false + }, + { + "name": "node20-jdk21", + "node_version": "20.18.0", + "node_major": "20", + "jdk_version": "21", + "base_image_tag": "20.18.0-jdk21", + "gradle_version": "8.5", + "sonar_version": "6.2.1.4610", + "cx_flow_version": "1.7.11", + "cx_flow_jar": "cx-flow.jar", + "sca_resolver_version": "2.12.36", + "is_latest": false + }, + { + "name": "node22-jdk21", + "node_version": "22.11.0", + "node_major": "22", + "jdk_version": "21", + "base_image_tag": "22.11.0-jdk21", + "gradle_version": "8.5", + "sonar_version": "6.2.1.4610", + "cx_flow_version": "1.7.11", + "cx_flow_jar": "cx-flow.jar", + "sca_resolver_version": "2.12.36", + "is_latest": true + } + ] +}