From c4f3a5b8751aac05ba48175b61560da8b2c24068 Mon Sep 17 00:00:00 2001 From: yy Date: Tue, 25 Mar 2025 15:36:21 +0800 Subject: [PATCH] ci: use matrix to build images. --- .github/workflows/docker-image.yml | 100 +++++++++++++--------------- Language/c/gcc-12.2.0/Dockerfile | 6 +- OS/debian-ssh/12.6/Dockerfiletmp | 41 ++++++++++++ OS/debian-ssh/project/entrypoint.sh | 4 +- script/build_and_push_images.sh | 65 ++++-------------- script/get_all_dockerfile.sh | 16 +++++ script/get_changed_dockerfile.sh | 28 ++++++++ script/get_changed_files.sh | 28 -------- script/get_image_name.sh | 15 +++++ 9 files changed, 166 insertions(+), 137 deletions(-) create mode 100644 OS/debian-ssh/12.6/Dockerfiletmp create mode 100644 script/get_all_dockerfile.sh create mode 100755 script/get_changed_dockerfile.sh delete mode 100755 script/get_changed_files.sh create mode 100644 script/get_image_name.sh diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 2a53c7ee..3b3c112d 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -4,82 +4,74 @@ on: workflow_dispatch: inputs: tag: - description: 'Tag for the Docker image' + description: 'tag for the Docker image' required: true default: 'latest' push: branches: - 'main' - paths: - - '**/Dockerfile' - jobs: + define-matrix: + runs-on: ubuntu-latest + outputs: + tag: ${{ steps.set_tag.outputs.tag }} + tag_cn: ${{ steps.set_tag.outputs.tag_cn }} + build_targets: ${{ steps.get_build_matrix.outputs.build_targets }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set up tag + id: set_tag + run: | + if [ -n "${{ inputs.tag }}" ]; then + tag=${{ inputs.tag }} + else + tag=${{ github.sha }}::6 + fi + tag_cn=$tag-cn + echo "tag=$tag" >> $GITHUB_OUTPUT + echo "tag_cn=$tag_cn" >> $GITHUB_OUTPUT + - name: Get build matrix + id: get_build_matrix + run: | + if [ -n "${{ inputs.tag }}" ]; then + build_targets=$(bash script/get_all_dockerfile.sh) + else + build_targets=$(bash script/get_changed_dockerfile.sh ${{ github.event.before }} ${{ github.sha }}) + fi + echo "build_targets=$build_targets" >> $GITHUB_OUTPUT build: runs-on: ubuntu-latest - + needs: define-matrix + strategy: + matrix: + build_target: ${{ fromJson(needs.define-matrix.outputs.build_targets) }} steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Set up QEMU uses: docker/setup-qemu-action@v3 - - - name: Set up tag - id: set_tag - run: | - if [ -n "$INPUT_TAG" ]; then - TAG=$INPUT_TAG - else - TAG=${COMMIT_ID::6} - fi - CN_TAG=$INPUT_TAG-cn - - echo "TAG=$TAG" >> $GITHUB_ENV - echo "CN_TAG=$CN_TAG" >> $GITHUB_ENV - echo "TAG=$TAG" >> $GITHUB_OUTPUT - echo "CN_TAG=$CN_TAG" >> $GITHUB_OUTPUT - - - name: Get changed files - id: getfile - run: | - bash script/get_changed_files.sh ${{ github.event.before }} ${{ github.sha }} - shell: bash - - - name: Echo output - run: | - echo "Changed files: ${{ env.DIFF_OUTPUT }}" - echo "Parent directories: ${{ env.PARENT_DIRS }}" - - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Login to ghcr.io uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GH_PAT }} - - name: Build and push image run: | - bash script/build_and_push_images.sh ${{ steps.set_tag.outputs.TAG }} ${{ steps.set_tag.outputs.CN_TAG }} - env: - USERNAME: ${{ github.repository_owner }} - COMMIT_ID: ${{ github.sha }} - shell: bash - - - uses: actions/checkout@v3 - - name: generate runtime yaml - run: | - bash script/generate_runtime_yaml.sh ${{ steps.set_tag.outputs.TAG }} ${{ steps.set_tag.outputs.CN_TAG }} - bash script/generate_json.sh ${{ steps.set_tag.outputs.TAG }} ${{ steps.set_tag.outputs.CN_TAG }} - env: - DOCKER_USERNAME: ${{ github.repository_owner }} - COMMIT_ID: ${{ github.sha }} - shell: bash - - - uses: stefanzweifel/git-auto-commit-action@v5 - with: - commit_message: auto generate runtime yaml + echo "build_target=$build_target" + echo "tag=${{ needs.define-matrix.outputs.tag }}" + echo "tag_cn=${{ needs.define-matrix.outputs.tag_cn }}" + image_name=$(bash script/get_image_name.sh ${{ github.repository_owner }} $build_target ${{ needs.define-matrix.outputs.tag }}) + image_name_cn=$(bash script/get_image_name.sh ${{ github.repository_owner }} $build_target ${{ needs.define-matrix.outputs.tag_cn }}) + echo "image_name=$image_name" >> $GITHUB_OUTPUT + echo "image_name_cn=$image_name_cn" >> $GITHUB_OUTPUT + is_cn=0 bash script/build_and_push_images.sh $build_target $image_name $is_cn + is_cn=1 bash script/build_and_push_images.sh $build_target $image_name_cn $is_cn + # TODO: generate runtime yaml and json diff --git a/Language/c/gcc-12.2.0/Dockerfile b/Language/c/gcc-12.2.0/Dockerfile index 0f76a20d..0b874c4a 100644 --- a/Language/c/gcc-12.2.0/Dockerfile +++ b/Language/c/gcc-12.2.0/Dockerfile @@ -1,7 +1,7 @@ FROM ghcr.io/labring-actions/devbox/debian-ssh-12.6:547a61 RUN cd /home/devbox/project && \ -rm -rf ./* + rm -rf ./* COPY /Language/c/project /home/devbox/project @@ -12,5 +12,5 @@ RUN apt-get update && \ chown -R devbox:devbox /home/devbox/project && \ chmod -R u+rw /home/devbox/project && \ chmod -R +x /home/devbox/project/entrypoint.sh - -RUN mkdir /root/.devbox \ No newline at end of file + +RUN mkdir /root/.devbox diff --git a/OS/debian-ssh/12.6/Dockerfiletmp b/OS/debian-ssh/12.6/Dockerfiletmp new file mode 100644 index 00000000..de1a47b9 --- /dev/null +++ b/OS/debian-ssh/12.6/Dockerfiletmp @@ -0,0 +1,41 @@ +FROM ghcr.io/labring-actions/devbox/debian:ce4733 + +COPY /script/startup.sh /usr/start/startup.sh + +RUN chmod +x /usr/start/startup.sh && \ + apt-get update && \ + apt-get install -y \ + dumb-init \ + wget \ + openssh-client \ + openssh-server && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* && \ + mkdir -p /run/sshd && \ + chmod 755 /run/sshd && \ + echo 'AllowTcpForwarding yes' >> /etc/ssh/sshd_config && \ + echo 'GatewayPorts yes' >> /etc/ssh/sshd_config && \ + echo 'X11Forwarding yes' >> /etc/ssh/sshd_config && \ + echo 'Port 22' >> /etc/ssh/sshd_config && \ + echo 'AuthorizedKeysFile /usr/start/.ssh/authorized_keys' >> /etc/ssh/sshd_config && \ + useradd -m -s /bin/bash devbox && \ + usermod -aG sudo devbox && \ + echo 'devbox ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers && \ + rm -rf /tmp/* && \ + mkdir -p /home/devbox/.ssh && \ + echo "devbox:devbox" | sudo chpasswd && \ + chown -R devbox:devbox /home/devbox/.ssh && \ + chmod -R 770 /home/devbox/.ssh + +USER devbox +COPY /OS/debian-ssh/project /home/devbox/project +RUN sudo chown -R devbox:devbox /home/devbox/project && \ + sudo chmod -R 777 /home/devbox/project + +USER root + +ENTRYPOINT ["/usr/bin/dumb-init", "--"] +CMD ["sudo", "-E", "/usr/start/startup.sh"] + +WORKDIR /home/devbox/project +EXPOSE 22 \ No newline at end of file diff --git a/OS/debian-ssh/project/entrypoint.sh b/OS/debian-ssh/project/entrypoint.sh index 5fddb409..4c5199e5 100644 --- a/OS/debian-ssh/project/entrypoint.sh +++ b/OS/debian-ssh/project/entrypoint.sh @@ -1 +1,3 @@ -./hello.sh \ No newline at end of file +#!/bin/bash + +./hello.sh diff --git a/script/build_and_push_images.sh b/script/build_and_push_images.sh index 4cca1d9f..00991a52 100644 --- a/script/build_and_push_images.sh +++ b/script/build_and_push_images.sh @@ -1,61 +1,24 @@ #!/bin/bash -# Print the input parent directories and difference output -echo "PARENT_DIRS=$PARENT_DIRS" -echo "DIFF_OUTPUT=$DIFF_OUTPUT" - -# Get tags from the input parameters -TAG=$1 -CN_TAG=$2 - -# Read the differences and parent directories into arrays -IFS=',' read -r -a DIFF_OUTPUT_ARRAY <<< "$DIFF_OUTPUT" -IFS=',' read -r -a PARENT_DIRS_ARRAY <<< "$PARENT_DIRS" - -# Print the contents of the arrays for debugging -echo "DIFF_OUTPUT array: ${DIFF_OUTPUT_ARRAY[@]}" -echo "PARENT_DIRS array: ${PARENT_DIRS_ARRAY[@]}" - -# Function to build and push Docker images -build_and_push_image() { - local dockerfile_path=$1 - local image_name=$2 +build_target=$1 +image_name=$2 +is_cn=$3 +function build_and_push_image() { docker buildx build --push \ - --file "$dockerfile_path" \ + --file "$build_target" \ --platform linux/amd64 \ - --tag "ghcr.io/$USERNAME/devbox/$image_name" \ + --tag "$image_name" \ . } -# Iterate over Dockerfile paths -for i in "${!DIFF_OUTPUT_ARRAY[@]}"; do - DOCKERFILE_PATH=${DIFF_OUTPUT_ARRAY[$i]} - PARENT_DIR=${PARENT_DIRS_ARRAY[$i]} - - # Extract parent path for further use - parent_path="${DOCKERFILE_PATH%/*}" - parent_path=$(dirname "$parent_path") - - # Create the English image name - IFS='/' read -ra ADDR <<< "$DOCKERFILE_PATH" - EN_IMAGE_NAME="${ADDR[1]}-$PARENT_DIR:$TAG" - - # Build and push the English Docker image - build_and_push_image "$DOCKERFILE_PATH" "$EN_IMAGE_NAME" - - # Check for the Chinese Dockerfile update script and handle accordingly - if [ -f "$parent_path/update_cn_dockerfile.sh" ]; then - bash "$parent_path/update_cn_dockerfile.sh" "$DOCKERFILE_PATH" - CN_IMAGE_NAME="${ADDR[1]}-$PARENT_DIR:$CN_TAG" +function execute_cn_patch() { + script_dir=$(dirname "$(dirname "$build_target")") + bash "$script_dir/update_cn_dockerfile.sh" "$build_target" +} - # Use a temporary Dockerfile for the Chinese image - TEMP_DOCKERFILE="${DOCKERFILE_PATH}tmp" - - # Build and push the Chinese Docker image - build_and_push_image "$TEMP_DOCKERFILE" "$CN_IMAGE_NAME" +if [ "$is_cn" -eq 1 ]; then + execute_cn_patch +fi - # Remove the temporary Dockerfile - rm "$TEMP_DOCKERFILE" - fi -done \ No newline at end of file +build_and_push_image diff --git a/script/get_all_dockerfile.sh b/script/get_all_dockerfile.sh new file mode 100644 index 00000000..fc0d9be4 --- /dev/null +++ b/script/get_all_dockerfile.sh @@ -0,0 +1,16 @@ +#!/bin/bash +DOCKERFILES=$(find . -name "Dockerfile" | sed 's|^\./||') +ARRAY_OUTPUT="[" +FIRST=true + +for DOCKERFILE in $DOCKERFILES; do + if [ "$FIRST" = true ]; then + ARRAY_OUTPUT+="\"$DOCKERFILE\"" + FIRST=false + else + ARRAY_OUTPUT+=",\"$DOCKERFILE\"" + fi +done + +ARRAY_OUTPUT+="]" +echo "$ARRAY_OUTPUT" diff --git a/script/get_changed_dockerfile.sh b/script/get_changed_dockerfile.sh new file mode 100755 index 00000000..34303468 --- /dev/null +++ b/script/get_changed_dockerfile.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +if [ "$#" -ne 2 ]; then + echo "Usage: $0 " + exit 1 +fi + +DIFF_OUTPUT=$(git diff --name-only "$1" "$2"|grep Dockerfile) + +ARRAY_OUTPUT="[" +FIRST=true + +for FILE_PATH in $DIFF_OUTPUT; do + if [[ ! -f "$FILE_PATH" ]]; then + echo "File $FILE_PATH does not exist, skipping." + continue + fi + + if [ "$FIRST" = true ]; then + ARRAY_OUTPUT+="\"$FILE_PATH\"" + FIRST=false + else + ARRAY_OUTPUT+=",\"$FILE_PATH\"" + fi +done + +ARRAY_OUTPUT+="]" +echo "$ARRAY_OUTPUT" diff --git a/script/get_changed_files.sh b/script/get_changed_files.sh deleted file mode 100755 index 2464537b..00000000 --- a/script/get_changed_files.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -if [ "$#" -ne 2 ]; then - echo "Usage: $0 " - exit 1 -fi - -DIFF_OUTPUT=$(git diff --name-only "$1" "$2"|grep Dockerfile) - -PARENT_DIRS=() -FILE_PATHS=() -for FILE_PATH in $DIFF_OUTPUT; do - if [[ ! -f "$FILE_PATH" ]]; then - echo "File $FILE_PATH does not exist, skipping." - continue - fi - PARENT_DIR=$(basename "$(dirname "$FILE_PATH")") - PARENT_DIRS+=("$PARENT_DIR") - FILE_PATHS+=("$FILE_PATH") -done - -PARENT_DIRS_STRING=$(IFS=,; echo "${PARENT_DIRS[*]}") -DIFF_OUTPUT_STRING=$(IFS=,; echo "${FILE_PATHS[*]}") -echo "PARENT_DIRS=$PARENT_DIRS_STRING" -echo "DIFF_OUTPUT=$DIFF_OUTPUT_STRING" - -echo "PARENT_DIRS=$PARENT_DIRS_STRING" >> "$GITHUB_ENV" -echo "DIFF_OUTPUT=$DIFF_OUTPUT_STRING" >> "$GITHUB_ENV" diff --git a/script/get_image_name.sh b/script/get_image_name.sh new file mode 100644 index 00000000..37e82850 --- /dev/null +++ b/script/get_image_name.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +if [ "$#" -ne 3 ]; then + echo "Usage: $0 " + exit 1 +fi + +USERNAME=$1 +BUILD_TARGET=$2 +TAG=$3 + +IFS='/' read -ra ADDR <<< "$BUILD_TARGET" +IMAGE_NAME="${ADDR[1]}-${ADDR[2]}" + +echo "ghcr.io/$USERNAME/devbox/$IMAGE_NAME:$TAG"