Skip to content

Build and Release

Build and Release #58

# Product release CI (java-chains release repo; formerly web-chains).
# Backend: Java-Chains/chains | SPA: in-tree java-chains-web-element (Vue Element Plus)
name: Build and Release
on:
workflow_dispatch:
inputs:
version:
description: "Release version without leading v (e.g. 2.0.0-beta3)"
required: true
type: string
source_ref:
description: "Source ref in Java-Chains/chains (tag, branch, or commit). Defaults to v<version>"
required: false
type: string
publish:
description: "Publish the GitHub Release immediately (skip draft). Default: draft only."
required: false
type: boolean
default: false
permissions:
contents: write
jobs:
# ====================================================
# Job 0: 解析发布元信息
# ====================================================
resolve_release_meta:
runs-on: ubuntu-latest
outputs:
release_version: ${{ steps.meta.outputs.release_version }}
release_tag: ${{ steps.meta.outputs.release_tag }}
source_ref: ${{ steps.meta.outputs.source_ref }}
is_prerelease: ${{ steps.meta.outputs.is_prerelease }}
publish_release: ${{ steps.meta.outputs.publish_release }}
docker_tags: ${{ steps.meta.outputs.docker_tags }}
chains_dev_jars_repository: ${{ steps.manifest.outputs.chains_dev_jars_repository }}
chains_dev_jars_ref: ${{ steps.manifest.outputs.chains_dev_jars_ref }}
java_echo_generator_repository: ${{ steps.manifest.outputs.java_echo_generator_repository }}
java_echo_generator_ref: ${{ steps.manifest.outputs.java_echo_generator_ref }}
java_memshell_generator_repository: ${{ steps.manifest.outputs.java_memshell_generator_repository }}
java_memshell_generator_ref: ${{ steps.manifest.outputs.java_memshell_generator_ref }}
chains_config_repository: ${{ steps.manifest.outputs.chains_config_repository }}
chains_config_ref: ${{ steps.manifest.outputs.chains_config_ref }}
steps:
- uses: actions/checkout@v4
- name: Resolve Release Metadata
id: meta
shell: bash
run: |
VERSION_INPUT="${{ inputs.version }}"
VERSION="${VERSION_INPUT#v}"
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
echo "Invalid version: $VERSION_INPUT"
echo "Use SemVer, for example: 2.0.0 or 2.0.0-beta3"
exit 1
fi
RELEASE_TAG="v$VERSION"
SOURCE_REF="${{ inputs.source_ref }}"
if [ -z "$SOURCE_REF" ]; then
SOURCE_REF="$RELEASE_TAG"
fi
if [[ "$VERSION" == *-* ]]; then
IS_PRERELEASE="true"
else
IS_PRERELEASE="false"
fi
# workflow_dispatch boolean → string "true"/"false"; default draft.
PUBLISH_INPUT="${{ inputs.publish }}"
if [ "$PUBLISH_INPUT" = "true" ]; then
PUBLISH_RELEASE="true"
else
PUBLISH_RELEASE="false"
fi
echo "release_version=$VERSION" >> "$GITHUB_OUTPUT"
echo "release_tag=$RELEASE_TAG" >> "$GITHUB_OUTPUT"
echo "source_ref=$SOURCE_REF" >> "$GITHUB_OUTPUT"
echo "is_prerelease=$IS_PRERELEASE" >> "$GITHUB_OUTPUT"
echo "publish_release=$PUBLISH_RELEASE" >> "$GITHUB_OUTPUT"
{
echo "docker_tags<<EOF"
echo "javachains/javachains:${VERSION}"
if [ "$IS_PRERELEASE" != "true" ]; then
echo "javachains/javachains:latest"
fi
echo "EOF"
} >> "$GITHUB_OUTPUT"
- name: Read Release Manifest
id: manifest
shell: bash
run: |
ruby <<'RUBY'
require 'yaml'
manifest = YAML.safe_load(File.read('.github/release-manifest.yml'), aliases: false)
dependencies = manifest.fetch('dependencies')
required = %w[
chains_dev_jars
java_echo_generator
java_memshell_generator
chains_config
]
File.open(ENV.fetch('GITHUB_OUTPUT'), 'a') do |out|
required.each do |name|
entry = dependencies[name] || abort("Missing dependency entry: #{name}")
repository = entry['repository'].to_s.strip
ref = entry['ref'].to_s.strip
abort("Missing repository for #{name}") if repository.empty?
abort("Missing ref for #{name}") if ref.empty?
out.puts "#{name}_repository=#{repository}"
out.puts "#{name}_ref=#{ref}"
end
end
RUBY
# ====================================================
# Job 1: 核心构建(适配 v2 模块与发行物)
# ====================================================
build:
needs: resolve_release_meta
runs-on: ubuntu-latest
outputs:
source_sha: ${{ steps.source_revision.outputs.source_sha }}
frontend_sha: ${{ steps.frontend.outputs.frontend_sha }}
env:
JAVA_VERSION: '8'
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
repository: Java-Chains/chains
ref: ${{ needs.resolve_release_meta.outputs.source_ref }}
token: ${{ secrets.DEPENDENCY_REPO_TOKEN }}
fetch-depth: 0
- name: Checkout Release Packaging Script
uses: actions/checkout@v4
with:
path: _release_ci
sparse-checkout: |
.github/scripts
sparse-checkout-cone-mode: false
clean: false
- name: Capture Source Revision
id: source_revision
shell: bash
run: |
echo "source_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
- name: Resolve Element Frontend Revision
id: frontend
shell: bash
run: |
test -f java-chains-web-element/package.json
test -f java-chains-web-element/pnpm-lock.yaml
FRONTEND_SHA="$(git log -1 --format=%H -- java-chains-web-element)"
FRONTEND_CT="$(git log -1 --format=%ct -- java-chains-web-element)"
echo "frontend_sha=${FRONTEND_SHA}" >> "$GITHUB_OUTPUT"
echo "SOURCE_DATE_EPOCH=${FRONTEND_CT}" >> "$GITHUB_ENV"
echo "Using in-tree java-chains-web-element @ ${FRONTEND_SHA}"
- name: Validate Source Version
shell: bash
run: |
EXPECTED_VERSION="${{ needs.resolve_release_meta.outputs.release_version }}"
POM_VERSION=$(sed -n '0,/<version>/s/.*<version>\([^<]*\)<\/version>.*/\1/p' pom.xml | head -n 1)
if [ -z "$POM_VERSION" ]; then
echo "Failed to read version from pom.xml"
exit 1
fi
if [ "$POM_VERSION" != "$EXPECTED_VERSION" ]; then
echo "Version mismatch:"
echo " source_ref: ${{ needs.resolve_release_meta.outputs.source_ref }}"
echo " pom.xml: $POM_VERSION"
echo " input: $EXPECTED_VERSION"
echo "Please bump/tag the source repo first, or pass the correct source_ref."
exit 1
fi
- name: Clone Pinned Dependency Repositories
env:
DEPENDENCY_REPO_TOKEN: ${{ secrets.DEPENDENCY_REPO_TOKEN }}
CHAINS_DEV_JARS_REPOSITORY: ${{ needs.resolve_release_meta.outputs.chains_dev_jars_repository }}
CHAINS_DEV_JARS_REF: ${{ needs.resolve_release_meta.outputs.chains_dev_jars_ref }}
JAVA_ECHO_GENERATOR_REPOSITORY: ${{ needs.resolve_release_meta.outputs.java_echo_generator_repository }}
JAVA_ECHO_GENERATOR_REF: ${{ needs.resolve_release_meta.outputs.java_echo_generator_ref }}
JAVA_MEMSHELL_GENERATOR_REPOSITORY: ${{ needs.resolve_release_meta.outputs.java_memshell_generator_repository }}
JAVA_MEMSHELL_GENERATOR_REF: ${{ needs.resolve_release_meta.outputs.java_memshell_generator_ref }}
CHAINS_CONFIG_REPOSITORY: ${{ needs.resolve_release_meta.outputs.chains_config_repository }}
CHAINS_CONFIG_REF: ${{ needs.resolve_release_meta.outputs.chains_config_ref }}
run: |
mkdir -p release-deps
clone_repo() {
local repository="$1"
local directory="$2"
local ref="$3"
local url="https://x-access-token:${DEPENDENCY_REPO_TOKEN}@github.com/${repository}.git"
echo "Cloning ${repository} @ ${ref}"
git clone "$url" "$directory"
git -C "$directory" checkout "$ref"
echo "Resolved $(git -C "$directory" rev-parse HEAD) for ${repository}"
}
clone_repo "$CHAINS_DEV_JARS_REPOSITORY" "release-deps/chains-dev-jars" "$CHAINS_DEV_JARS_REF"
clone_repo "$JAVA_ECHO_GENERATOR_REPOSITORY" "release-deps/java-echo-generator" "$JAVA_ECHO_GENERATOR_REF"
clone_repo "$JAVA_MEMSHELL_GENERATOR_REPOSITORY" "release-deps/java-memshell-generator" "$JAVA_MEMSHELL_GENERATOR_REF"
clone_repo "$CHAINS_CONFIG_REPOSITORY" "release-deps/chains-config" "$CHAINS_CONFIG_REF"
- name: Set up Temurin JDK ${{ env.JAVA_VERSION }}
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: ${{ env.JAVA_VERSION }}
cache: 'maven'
- name: Set up Maven
uses: stCarolas/setup-maven@v5
with:
maven-version: 3.9.6
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
- uses: pnpm/action-setup@v4
with:
version: 9
- name: Cache Maven dependencies
uses: actions/cache@v4
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-v2-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-v2-
${{ runner.os }}-maven-
- name: Clone and Install Dev Jars
run: |
(
cd release-deps/chains-dev-jars
bash mvn_install.sh
)
- name: Build and Install Generators
run: |
(
cd release-deps/java-echo-generator
mvn clean install -DskipTests
)
(
cd release-deps/java-memshell-generator
mvn clean install -DskipTests
)
- name: Build Ship Artifacts (Element SPA + CLI)
run: |
# Product SPA = java-chains-web-element (pnpm → generated-resources/static).
# Prefer in-tree ship script from chains; fall back to release-repo copy.
if [ ! -f scripts/frontend/package-java-chains-web-element.sh ]; then
install -m 0755 _release_ci/.github/scripts/package-java-chains-web-element.sh \
scripts/frontend/package-java-chains-web-element.sh
fi
# ONE Maven invocation: second `mvn -am package` without -Pfrontend reuses
# server target/ but a new maven.build.timestamp → Vector A session mismatch.
# Product surface: server + java-chains-cli (no java-chains-sdk).
mvn -pl java-chains-server,java-chains-cli -am clean package \
-DskipTests -Pfrontend,with-exploits \
-Dfrontend.working.directory="${PWD}/java-chains-web-element" \
-Dfrontend.package.script="${PWD}/scripts/frontend/package-java-chains-web-element.sh"
- name: Prepare Base Artifacts
run: |
mkdir -p release_base
VERSION="${{ needs.resolve_release_meta.outputs.release_version }}"
pick_first() {
local candidate
for candidate in "$@"; do
if [ -f "$candidate" ]; then
printf '%s\n' "$candidate"
return 0
fi
done
return 1
}
# 1. Server Spring Boot fat jar (SPA embedded). Publish as java-chains.jar.
SERVER_JAR="$(pick_first \
"java-chains-${VERSION}-exec.jar" \
"java-chains-server-${VERSION}-exec.jar" \
"java-chains-server/target/java-chains-server-${VERSION}-exec.jar" \
"java-chains-server/target/java-chains-${VERSION}-exec.jar" \
)" || true
if [ -z "${SERVER_JAR:-}" ]; then
SERVER_JAR="$(find . -maxdepth 2 -type f \( \
-name "java-chains-*-exec.jar" -o -name "java-chains-server-*-exec.jar" \
\) ! -name "*-sources.jar" ! -name "*-javadoc.jar" | sort | head -n 1 || true)"
fi
if [ -f "${SERVER_JAR:-}" ]; then
echo "Found Server Jar: ${SERVER_JAR}"
cp "$SERVER_JAR" release_base/java-chains.jar
else
echo "Error: java-chains server exec jar not found"
find . -maxdepth 3 -type f -name "*.jar" | sort | head -n 80
exit 1
fi
# 2. Product CLI fat jar (java-chains-cli). Keep a thin remote jar if present.
CLI_JAR="$(pick_first \
"java-chains-cli/target/java-chains-cli-${VERSION}-jar-with-dependencies.jar" \
"java-chains-cli/target/java-chains-cli-${VERSION}.jar" \
)" || true
if [ -z "${CLI_JAR:-}" ]; then
CLI_JAR="$(find java-chains-cli/target -type f -name "java-chains-cli-*-jar-with-dependencies.jar" 2>/dev/null | sort | head -n 1 || true)"
fi
if [ -f "${CLI_JAR:-}" ]; then
echo "Found CLI Jar: ${CLI_JAR}"
cp "$CLI_JAR" release_base/java-chains-cli.jar
else
echo "Error: java-chains-cli fat jar not found"
exit 1
fi
CLI_REMOTE_JAR="$(pick_first \
"java-chains-cli-remote/target/java-chains-cli-remote-${VERSION}-jar-with-dependencies.jar" \
"java-chains-cli-remote/target/java-chains-cli-remote-${VERSION}.jar" \
)" || true
if [ -f "${CLI_REMOTE_JAR:-}" ]; then
echo "Found CLI remote Jar: ${CLI_REMOTE_JAR}"
cp "$CLI_REMOTE_JAR" release_base/java-chains-cli-remote.jar
fi
# 3. Runtime config (plugins / third-libs / presets)
cp -r release-deps/chains-config release_base/chains-config
rm -rf release_base/chains-config/.git
if [ -d chains-config ]; then
# Overlay any in-tree config additions (e.g. presets) without wiping deps.
cp -a chains-config/. release_base/chains-config/ 2>/dev/null || true
rm -rf release_base/chains-config/.git
fi
# ── 源码防泄漏:销毁所有源码,确保 artifact 只含编译产物 ──
- name: Purge Source Code
if: always()
run: |
rm -rf release-deps
rm -rf ~/.m2/repository
if find release_base -type f \( \
-name "*.java" -o -name "*.go" -o -name "*.ts" -o -name "*.tsx" \
-o -name "*.vue" -o -name "*.jsx" -o -name "*.py" \
-o -name "*-sources.jar" -o -name "*-javadoc.jar" \
-o -name ".git" -o -name ".gitignore" \
-o -name "pom.xml" -o -name "package.json" -o -name "go.mod" \
\) | grep -q .; then
echo "ERROR: Source code files detected in release artifacts!"
find release_base -type f \( \
-name "*.java" -o -name "*.go" -o -name "*.ts" -o -name "*.tsx" \
-o -name "*.vue" -o -name "*.jsx" -o -name "*.py" \
-o -name "*-sources.jar" -o -name "*-javadoc.jar" \
-o -name ".git" -o -name ".gitignore" \
-o -name "pom.xml" -o -name "package.json" -o -name "go.mod" \
\)
exit 1
fi
find release_base -type d -name ".git" -exec rm -rf {} + 2>/dev/null || true
echo "Artifact contents:"
find release_base -type f | sort
- name: Upload Base Artifacts
uses: actions/upload-artifact@v4
with:
name: base-artifacts
path: release_base/
# ====================================================
# Job 2: Create Release
# ====================================================
create_release:
needs: [ resolve_release_meta, build ]
runs-on: ubuntu-latest
# No actions/* uses: — avoids GitHub "GetResolveActionsDownloadInfo" 503 during Set up job.
# Notes are generated inline; gh is preinstalled on ubuntu-latest.
steps:
- name: Create GitHub Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
RELEASE_TAG="${{ needs.resolve_release_meta.outputs.release_tag }}"
RELEASE_VERSION="${{ needs.resolve_release_meta.outputs.release_version }}"
SOURCE_REF="${{ needs.resolve_release_meta.outputs.source_ref }}"
SOURCE_SHA="${{ needs.build.outputs.source_sha }}"
FRONTEND_SHA="${{ needs.build.outputs.frontend_sha }}"
IS_PRERELEASE="${{ needs.resolve_release_meta.outputs.is_prerelease }}"
PUBLISH_RELEASE="${{ needs.resolve_release_meta.outputs.publish_release }}"
if gh release view "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" > /dev/null 2>&1; then
echo "Release $RELEASE_TAG already exists, skip creation."
exit 0
fi
cat > release-notes.txt <<EOF
Auto-generated release for version ${RELEASE_VERSION}
Backend repository: Java-Chains/chains
Backend ref: ${SOURCE_REF}
Backend commit: ${SOURCE_SHA}
Frontend: java-chains-web-element (Vue3 + Element Plus, in-tree)
Frontend commit: ${FRONTEND_SHA}
Artifacts:
- java-chains-\${VERSION}.tar.gz — Server (SPA from java-chains-web-element) + chains-config
- java-chains-\${VERSION}-<platform>.tar.gz|zip — Server + bundled JDK 8
- java-chains-cli-\${VERSION}.tar.gz — Product CLI fat jar + chains-config
- Docker: javachains/javachains:${RELEASE_VERSION}
EOF
ARGS=(
"$RELEASE_TAG"
--title "Release $RELEASE_TAG"
--repo "$GITHUB_REPOSITORY"
--notes-file release-notes.txt
)
# Default: draft. Set workflow input publish=true to publish immediately.
if [ "$PUBLISH_RELEASE" != "true" ]; then
ARGS+=(--draft)
echo "Creating DRAFT release $RELEASE_TAG"
else
echo "Creating PUBLISHED release $RELEASE_TAG (publish=true)"
fi
if [ "$IS_PRERELEASE" = "true" ]; then
ARGS+=(--prerelease)
fi
gh release create "${ARGS[@]}"
# ====================================================
# Job 3: 矩阵打包 (Server + JDK)
# ====================================================
bundle_assets:
needs: [ resolve_release_meta, build, create_release ]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- os_api: linux
arch_api: x64
suffix: linux-amd64
ext: tar.gz
- os_api: linux
arch_api: aarch64
suffix: linux-aarch64
ext: tar.gz
- os_api: windows
arch_api: x64
suffix: windows-amd64
ext: zip
- os_api: windows
arch_api: arm64
suffix: windows-arm64
ext: zip
- os_api: mac
arch_api: x64
suffix: macos-intel
ext: tar.gz
- os_api: mac
arch_api: aarch64
suffix: macos-m-series
ext: tar.gz
steps:
- uses: actions/download-artifact@v4
with:
name: base-artifacts
path: base
- name: Download JDK 8
run: |
API_URL="https://api.adoptium.net/v3/binary/latest/8/ga/${{ matrix.os_api }}/${{ matrix.arch_api }}/jdk/hotspot/normal/eclipse"
USE_AZUL="false"
if [ "${{ matrix.os_api }}" = "mac" ] && [ "${{ matrix.arch_api }}" = "aarch64" ]; then
USE_AZUL="true"
fi
if [ "${{ matrix.os_api }}" = "windows" ] && [ "${{ matrix.arch_api }}" = "arm64" ]; then
API_URL="https://api.adoptium.net/v3/binary/latest/8/ga/windows/x64/jdk/hotspot/normal/eclipse"
fi
if [ "$USE_AZUL" = "true" ]; then
AZUL_OS="${{ matrix.os_api }}"
if [ "$AZUL_OS" = "mac" ]; then
AZUL_OS="macos"
fi
API_URL="https://api.azul.com/zulu/download/community/v1.0/bundles/latest/binary/?jdk_version=8&os=$AZUL_OS&arch=${{ matrix.arch_api }}&bundle_type=jdk&ext=${{ matrix.ext }}"
fi
if [ "${{ matrix.ext }}" = "zip" ]; then
curl -L "$API_URL" -o jdk_bundle.zip
unzip -q jdk_bundle.zip -d jdk_extracted
else
curl -L "$API_URL" -o jdk_bundle.tar.gz
mkdir jdk_extracted
tar -xzf jdk_bundle.tar.gz -C jdk_extracted
fi
SUBDIR=$(ls jdk_extracted | head -n 1)
mv "jdk_extracted/$SUBDIR" jdk_final
if [ "${{ matrix.os_api }}" = "mac" ] && [ -d "jdk_final/Contents/Home" ]; then
mv jdk_final/Contents/Home jdk_real
rm -rf jdk_final
mv jdk_real jdk_final
fi
- name: Create Distribution Structure
run: |
DIST_DIR="java-chains-${{ needs.resolve_release_meta.outputs.release_version }}-${{ matrix.suffix }}"
mkdir -p "$DIST_DIR"
cp base/java-chains.jar "$DIST_DIR/"
cp -r base/chains-config "$DIST_DIR/"
mv jdk_final "$DIST_DIR/jdk"
echo "DIST_DIR=$DIST_DIR" >> "$GITHUB_ENV"
- name: Generate Start Scripts
run: |
cd "${{ env.DIST_DIR }}"
if [ "${{ matrix.os_api }}" != "windows" ]; then
printf '%s\n' \
'#!/bin/bash' \
'BASE_DIR=$(cd "$(dirname "$0")" && pwd)' \
'cd "$BASE_DIR"' \
'exec "$BASE_DIR/jdk/bin/java" -jar "$BASE_DIR/java-chains.jar"' \
> start.sh
chmod +x start.sh
else
printf '%s\r\n' \
'@echo off' \
'set "BASE_DIR=%~dp0"' \
'cd /d "%BASE_DIR%"' \
'"%BASE_DIR%jdk\bin\java.exe" -jar "%BASE_DIR%java-chains.jar"' \
'pause' \
> start.bat
fi
- name: Compress and Upload
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
RELEASE_TAG="${{ needs.resolve_release_meta.outputs.release_tag }}"
ASSET_NAME="${{ env.DIST_DIR }}.${{ matrix.ext }}"
if [ "${{ matrix.ext }}" = "zip" ]; then
zip -r -q "$ASSET_NAME" "${{ env.DIST_DIR }}"
else
tar -czf "$ASSET_NAME" "${{ env.DIST_DIR }}"
fi
gh release upload "$RELEASE_TAG" "$ASSET_NAME" --clobber --repo "$GITHUB_REPOSITORY"
# ====================================================
# Job 4: 上传通用包 / CLI / SDK
# ====================================================
upload_standard_assets:
needs: [ resolve_release_meta, build, create_release ]
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
name: base-artifacts
path: base
- name: Create and Upload Assets
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
RELEASE_TAG="${{ needs.resolve_release_meta.outputs.release_tag }}"
RELEASE_VERSION="${{ needs.resolve_release_meta.outputs.release_version }}"
cd base
tar -czvf "java-chains-${RELEASE_VERSION}.tar.gz" java-chains.jar chains-config
gh release upload "$RELEASE_TAG" "java-chains-${RELEASE_VERSION}.tar.gz" --clobber --repo "$GITHUB_REPOSITORY"
mkdir cli_dist
cp java-chains-cli.jar cli_dist/
cp -r chains-config cli_dist/
if [ -f java-chains-cli-remote.jar ]; then
cp java-chains-cli-remote.jar cli_dist/
fi
tar -czvf "java-chains-cli-${RELEASE_VERSION}.tar.gz" -C cli_dist .
gh release upload "$RELEASE_TAG" "java-chains-cli-${RELEASE_VERSION}.tar.gz" --clobber --repo "$GITHUB_REPOSITORY"
# ====================================================
# Job 5: Docker Build
# ====================================================
docker_build:
needs: [ resolve_release_meta, build ]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: base-artifacts
path: .
- name: Prepare Docker context
run: |
# Docker image only needs the server jar + chains-config
rm -f java-chains-cli.jar java-chains-cli-remote.jar
test -f java-chains.jar
test -d chains-config
ls -la
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- uses: docker/build-push-action@v6
with:
file: Dockerfile
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ needs.resolve_release_meta.outputs.docker_tags }}