logstash:7.12.1 #150
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: docker image mirror | |
on: | |
issues: | |
types: [opened] | |
env: | |
TARGET_REGISTRIES: "ygqygq2:docker.io/ygqygq2, [email protected]:registry.cn-hangzhou.aliyuncs.com/img_mirror" | |
RED: \033[1;31m | |
GREEN: \033[1;32m | |
YELLOW: \033[1;33m | |
BLUE: \033[1;34m | |
PURPLE: \033[1;35m | |
CYAN: \033[1;36m | |
BLANK: \033[0m | |
jobs: | |
skopeo_sync: | |
runs-on: ubuntu-latest | |
outputs: | |
DOCKER_IMAGE: ${{ steps.setEnvVars.outputs.DOCKER_IMAGE }} | |
TARGET_DOCKER_IMAGE: ${{ steps.setEnvVars.outputs.TARGET_DOCKER_IMAGE }} | |
steps: | |
- name: Get porter issues | |
id: pullIssuesPorter | |
uses: actions/github-script@v7 | |
with: | |
github-token: ${{secrets.GITHUB_TOKEN}} | |
script: | | |
// 使用 title 获取镜像名和tag | |
const title = context?.payload?.issue?.title; | |
// 使用 body 获取其它参数 | |
const body = context?.payload?.issue?.body || ''; | |
const reg = new RegExp("\\[PORTER\\]", "g"); | |
let docker_image = title.replace(reg, "").trim(); | |
const issues_author = context?.payload?.issue?.user?.login; | |
// 为了防止 image 不带tag,自动添加 latest | |
if(!docker_image.includes(":")) { | |
docker_image = `${docker_image}:latest` | |
} | |
let comment_body = ''; | |
let is_error = false; | |
if( docker_image.includes("@")){ | |
is_error = true; | |
comment_body = '@' + issues_author +' 拉取镜像不支持带摘要信息,请去除 @部分' | |
}else{ | |
comment_body = `构建进展,详见 [构建任务](https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${{github.run_id}})` | |
} | |
const issuesComment = await github.rest.issues.createComment({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: context.issue.number, | |
body: comment_body | |
}); | |
console.log("create issues comment resp:", issuesComment["status"]); | |
if(is_error){ | |
core.setFailed("Error"); | |
}else if (!docker_image){ | |
core.setFailed("No Images"); | |
} | |
core.setOutput('DOCKER_IMAGE', docker_image); | |
core.setOutput('BUILD_ARGS', body); | |
- name: Set environment variables | |
id: setEnvVars | |
run: | | |
DOCKER_IMAGE="${{ steps.pullIssuesPorter.outputs.DOCKER_IMAGE }}" | |
if [[ "$DOCKER_IMAGE" == *.*/* ]]; then | |
PROCESSED_IMAGE=$(echo "$DOCKER_IMAGE" | sed 's@^[^/]*/@@' | sed 's@/@.@g') | |
else | |
PROCESSED_IMAGE=$(echo "$DOCKER_IMAGE" | sed 's@/@.@g') | |
fi | |
echo "DOCKER_IMAGE=$DOCKER_IMAGE" >> $GITHUB_ENV | |
echo "TARGET_DOCKER_IMAGE=$PROCESSED_IMAGE" >> $GITHUB_ENV | |
echo "BUILD_ARGS=${{ steps.pullIssuesPorter.outputs.BUILD_ARGS }}" >> $GITHUB_ENV | |
echo "DOCKER_IMAGE=$DOCKER_IMAGE" >> $GITHUB_OUTPUT | |
echo "TARGET_DOCKER_IMAGE=$PROCESSED_IMAGE" >> $GITHUB_OUTPUT | |
echo "BUILD_ARGS=${{ steps.pullIssuesPorter.outputs.BUILD_ARGS }}" >> $GITHUB_OUTPUT | |
- name: Setup go | |
uses: actions/setup-go@v5 | |
with: | |
go-version: '>=1.23.0' | |
- name: Install latest skopeo | |
run: | | |
echo -e "${PURPLE}> 🚜 Installing skopeo ${BLANK}" | |
sudo apt-get update | |
sudo apt-get install -y \ | |
btrfs-progs \ | |
libassuan-dev \ | |
libbtrfs-dev \ | |
libdevmapper-dev \ | |
libgpgme-dev \ | |
libgpg-error-dev \ | |
go-md2man \ | |
libseccomp-dev \ | |
libselinux1-dev \ | |
pkg-config \ | |
runc \ | |
uidmap | |
sudo git clone https://github.com/containers/skopeo /tmp/skopeo | |
cd /tmp/skopeo && sudo make bin/skopeo | |
skopeo_path=$(which skopeo) | |
sudo cp /tmp/skopeo/bin/skopeo $skopeo_path | |
- name: Sync image with skopeo | |
id: syncImage | |
shell: bash | |
run: | | |
echo -e "${PURPLE}> 🚜 Syncing docker images with skopeo ${BLANK}" | |
echo -e "${YELLOW}> Using skopeo version: ${BLANK}" | |
skopeo --version | |
RESULT=1 | |
TARGET_REGISTRIES="${{ env.TARGET_REGISTRIES }}" | |
IFS=',' read -ra REGISTRIES <<< "$TARGET_REGISTRIES" | |
for REGISTRY in "${REGISTRIES[@]}"; do | |
USERNAME=$(echo $REGISTRY | cut -d':' -f1) | |
REPO=$(echo $REGISTRY | cut -d':' -f2) | |
TARGET_IMAGE="${REPO}/${TARGET_DOCKER_IMAGE}" | |
echo -e "${YELLOW}> 🐳 Docker source repository ${BLANK}" | |
echo -e "${YELLOW}> 📦 Transfer docker images from ${DOCKER_IMAGE} to ${TARGET_IMAGE} ${BLANK}" | |
skopeo copy -a \ | |
--dest-creds=${USERNAME}:${{ secrets.DOCKER_PASSWORD }} \ | |
${BUILD_ARGS} \ | |
docker://${DOCKER_IMAGE} \ | |
docker://${TARGET_IMAGE} && \ | |
RESULT=$((RESULT * 0)) || \ | |
RESULT=$((RESULT * 1)) | |
done | |
echo "SKOPEO_RESULT=${RESULT}" >> $GITHUB_OUTPUT | |
echo -e "${YELLOW}> ✅ Sync is complete. See details above ${BLANK}" | |
docker_sync: | |
runs-on: ubuntu-latest | |
needs: skopeo_sync | |
if: ${{ needs.skopeo_sync.outputs.SKOPEO_RESULT == 1 }} | |
env: | |
DOCKER_IMAGE: ${{ needs.skopeo_sync.outputs.DOCKER_IMAGE }} | |
TARGET_DOCKER_IMAGE: ${{ needs.skopeo_sync.outputs.TARGET_DOCKER_IMAGE }} | |
steps: | |
- name: Set up QEMU | |
uses: docker/setup-qemu-action@v3 | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Parse target registries | |
id: parseRegistries | |
run: | | |
TARGET_REGISTRIES="${{ env.TARGET_REGISTRIES }}" | |
IFS=',' read -ra REGISTRIES <<< "$TARGET_REGISTRIES" | |
INDEX=1 | |
for REGISTRY in "${REGISTRIES[@]}"; do | |
USERNAME=$(echo $REGISTRY | cut -d':' -f1) | |
REPO=$(echo $REGISTRY | cut -d':' -f2) | |
echo "USERNAME${INDEX}=$USERNAME" >> $GITHUB_ENV | |
echo "REPO${INDEX}=$REPO" >> $GITHUB_ENV | |
INDEX=$((INDEX + 1)) | |
done | |
- name: Login to Docker Registry 1 | |
uses: docker/login-action@v3 | |
with: | |
username: ${{ env.USERNAME1 }} | |
password: ${{ secrets.DOCKER_PASSWORD }} | |
- name: Login to Docker Registry 2 | |
uses: docker/login-action@v3 | |
with: | |
registry: ${{ env.REPO2 }} | |
username: ${{ env.USERNAME2 }} | |
password: ${{ secrets.DOCKER_PASSWORD }} | |
- name: Pull image and push to docker registries | |
shell: bash | |
run: | | |
IFS=',' read -ra REGISTRIES <<< "$TARGET_REGISTRIES" | |
for REGISTRY in "${REGISTRIES[@]}"; do | |
USERNAME=$(echo $REGISTRY | cut -d':' -f1) | |
REPO=$(echo $REGISTRY | cut -d':' -f2) | |
TARGET_IMAGE="${REPO}/${TARGET_DOCKER_IMAGE}" | |
echo -e "> 📦 Transfer docker images from ${DOCKER_IMAGE} to ${TARGET_IMAGE}" | |
# Create and push a new manifest list for multi-architecture support | |
docker buildx imagetools create -t ${TARGET_IMAGE} ${DOCKER_IMAGE} | |
done | |
echo -e "> ✅ Sync is complete. See details above" | |
close_issue: | |
runs-on: ubuntu-latest | |
needs: [skopeo_sync, docker_sync] | |
if: always() | |
steps: | |
- name: Success check | |
id: successCheck | |
run: | | |
if [[ "${{ needs.skopeo_sync.result }}" == "success" || "${{ needs.docker_sync.result }}" == "success" ]]; then | |
echo "SUCCESS=true" >> $GITHUB_ENV | |
else | |
echo "SUCCESS=false" >> $GITHUB_ENV | |
fi | |
- name: Close Porter Issues | |
id: closePorterIssues | |
uses: actions/github-script@v7 | |
with: | |
github-token: ${{secrets.GITHUB_TOKEN}} | |
script: | | |
const issuesResponse = await github.rest.issues.update({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: context.issue.number, | |
state: 'closed' | |
}); | |
console.log("update issues resp:", issuesResponse["status"] == 200 ? "success" : "failed"); | |
let comment_body = `转换失败,详见 [构建任务](https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${{github.run_id}})`; | |
let success = process.env.SUCCESS === "true"; | |
console.log("is success?", success); | |
let labels = []; | |
if (success) { | |
let targetRegistries = "${{ env.TARGET_REGISTRIES }}".split(","); | |
let dockerImage = "${{ needs.skopeo_sync.outputs.DOCKER_IMAGE }}"; | |
let transferImages = targetRegistries.map(registry => { | |
let [username, repo] = registry.split(":"); | |
let imageName; | |
let firstSlashIndex = dockerImage.indexOf('/'); | |
if (firstSlashIndex !== -1 && dockerImage.substring(0, firstSlashIndex).includes('.')) { | |
imageName = dockerImage.substring(firstSlashIndex + 1).replace(/\//g, '.').replace(/\s+/g, ''); | |
} else { | |
imageName = dockerImage.replace(/\s+/g, '').replace(/\//g, '.'); | |
} | |
return `${repo}/${imageName}`; | |
}); | |
comment_body = "转换完成 <br/>\n```bash \n#原镜像\n${{ needs.skopeo_sync.outputs.DOCKER_IMAGE }}\n\n\n#转换后镜像\n"; | |
transferImages.forEach(image => { | |
comment_body += `${image}\n`; | |
}); | |
comment_body += "\n\n```"; | |
labels = ['success']; | |
} else { | |
const jobsResponse = await github.request(`GET /repos/${context.repo.owner}/${context.repo.repo}/actions/runs/${{github.run_id}}/jobs`, { | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
run_id: ${{ github.run_id }} | |
}); | |
console.log("jobs", jobsResponse['data']); | |
comment_body += "\n\n 日志:\n\n"; | |
for (let job of jobsResponse['data']['jobs']) { | |
comment_body += "- [" + job.name + "](" + job.html_url + ")"; | |
} | |
labels = ['failure']; | |
} | |
// 创建 issues comment | |
const issuesComment = await github.rest.issues.createComment({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: context.issue.number, | |
body: comment_body | |
}); | |
console.log("create issues comment resp:", issuesComment["status"] == 201 ? "success" : "failed"); | |
// 更新 issues label | |
if (labels) { | |
await github.rest.issues.addLabels({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: context.issue.number, | |
labels: labels | |
}); | |
} |