feat:add build-and-push-wasm-plugin-image.yaml by Beatrueman · Pull Request #1069 · alibaba/higress

Ⅰ. Describe what this PR did

功能:添加了利用 GitHub Actions 来自动完成相应的镜像构建和发布工作的Workflow。支持通过push tag和手动触发两种方式。同时也遵循使用oras打包工具。
特点:完全按照Wasm 插件镜像规范进行镜像打包。

更新:

  1. 添加了查找文件的逻辑,会在插件目录中查找spec.yamlREADME.mdREADME-{lang}.md三个文件,有则在打包推送镜像时设置相应的media type
  2. 修改了review后存在的问题。
  3. 修改了builder容器的启动命令为 docker run -itd --name builder xxx /bin/bash,之前使用sleep 99999是希望容器保持后台持续运行,这样只适合测试容器,不适合在生产环境中使用。
  4. 重新提交PR是因为错误地提交了一些没用的commit,不太会删除,担心破坏仓库并且为了保持PR整洁所以重新提交。

Ⅱ. Does this pull request fix one issue?

fixes #1052

Ⅳ. Describe how to verify it

1.准备工作
添加Repository Secrets和 Repository variables。
img
img
2.通过push tag触发,先查找相关文件,然后将特定的插件打包成镜像并推送至指定仓库。
image

image-20240629120147125image-20240629125144171
image-20240629125028239
3.人工触发,指定插件名和版本号
51e1fc7ab267c66492ecbcfb43cd23d0image

Ⅴ. Special notes for reviews

这是我第一次参与开源贡献,希望能有所帮助!

name: Build and Push Wasm Plugin Image

on:
push:
tags:
- "wasm-go-*-v*.*.*" # 匹配 wasm-go-{pluginName}-vX.Y.Z 格式的标签
workflow_dispatch:
inputs:
plugin_name:
description: 'Name of the plugin'
required: true
type: string
version:
description: 'Version of the plugin (optional, without leading v)'
required: false
type: string

jobs:
build-and-push-image:
runs-on: ubuntu-latest
environment:
name: image-registry-msg
env:
IMAGE_REGISTRY_SERVICE: ${{ vars.IMAGE_REGISTRY_SERVICE || 'higress-registry.cn-hangzhou.cr.aliyuncs.com' }}
IMAGE_REPOSITORY: ${{ vars.IMAGE_REPOSITORY || 'plugins' }}
GO_VERSION: 1.19
TINYGO_VERSION: 0.25.0
ORAS_VERSION: 1.0.0
steps:
- name: Set plugin_name and version from inputs or ref_name
id: set_vars
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
plugin_name="${{ github.event.inputs.plugin_name }}"
version="${{ github.event.inputs.version }}"
else
ref_name=${{ github.ref_name }}
plugin_name=${ref_name#*-*-} # 删除插件名前面的字段(wasm-go-)
plugin_name=${plugin_name%-*} # 删除插件名后面的字段(-vX.Y.Z)
version=$(echo "$ref_name" | awk -F'v' '{print $2}')
fi

echo "PLUGIN_NAME=$plugin_name" >> $GITHUB_ENV
echo "VERSION=$version" >> $GITHUB_ENV

- name: Checkout code
uses: actions/checkout@v3

- name: File Check
run: |
workspace=${{ github.workspace }}/plugins/wasm-go/extensions/${PLUGIN_NAME}
push_command="./plugin.tar.gz:application/vnd.oci.image.layer.v1.tar+gzip"

# 查找spec.yaml
if [ -f "${workspace}/spec.yaml" ]; then
echo "spec.yaml exists"
push_command="$push_command ./spec.yaml:application/vnd.module.wasm.spec.v1+yaml"
fi

# 查找README.md
case "$(ls ${workspace}/README*.md 2>/dev/null)" in
*"README.md"*)
echo "README.md exists"
push_command="$push_command ./README.md:application/vnd.module.wasm.doc.v1+markdown"
;;
esac

# 查找README_{lang}.md
for file in ${workspace}/README_*.md; do
if [ -f "$file" ]; then
file_name=$(basename $file)
echo "$file_name exists"
lang=$(basename $file | sed 's/README_//; s/.md//')
push_command="$push_command ./$file_name:application/vnd.module.wasm.doc.v1.$lang+markdown"
fi
done

echo "PUSH_COMMAND=\"$push_command\"" >> $GITHUB_ENV

- name: Run a wasm-go-builder
env:
PLUGIN_NAME: ${{ env.PLUGIN_NAME }}
BUILDER_IMAGE: higress-registry.cn-hangzhou.cr.aliyuncs.com/plugins/wasm-go-builder:go${{ env.GO_VERSION }}-tinygo${{ env.TINYGO_VERSION }}-oras${{ env.ORAS_VERSION }}
run: |
docker run -itd --name builder -v ${{ github.workspace }}:/workspace -e PLUGIN_NAME=${{ env.PLUGIN_NAME }} --rm ${{ env.BUILDER_IMAGE }} /bin/bash

- name: Build Image and Push
run: |

push_command=${{ env.PUSH_COMMAND }}
push_command=${push_command#\"}
push_command=${push_command%\"} # 删除PUSH_COMMAND中的双引号,确保oras push正常解析

command="
cd /workspace/plugins/wasm-go/extensions/${PLUGIN_NAME}
go mod tidy
tinygo build -o ./plugin.wasm -scheduler=none -target=wasi ./main.go
tar czvf plugin.tar.gz /workspace/plugins/wasm-go/extensions/${PLUGIN_NAME}/plugin.wasm
echo ${{ secrets.REGISTRY_PASSWORD }} | oras login -u ${{ secrets.REGISTRY_USERNAME }} --password-stdin ${{ env.IMAGE_REGISTRY_SERVICE }}
oras push ${IMAGE_REGISTRY_SERVICE}/${IMAGE_REPOSITORY}:${VERSION} ${push_command}
"
docker exec builder bash -c "$command"