Skip to content

welan release

welan release #8

Workflow file for this run

name: welan release
# 第一步,配置自己的上游仓库地址。
# 第二步,根据 CI 输入的 version 号,确保它是一个上游的 tag。如果输入的 version 号为空,那么自动从上游的 tag 里面获取最新的 tag 作为 version 号来工作。
# 第三步:获取上游对应版本的代码,在当前仓库的缺省分支上进行 Rebase。如果 Rebase 失败,需要把具体的冲突代码和文件打印成日志,然后报错退出。
# 第四步,我们运行 run 命令相关模块测试,确保 rebase 后行为正确且无边际回归。
# 第五步,我们分别构建 macOS、ARM 的 Linux、x86 的 Linux、ARM 的二进制。
# 第 6 步,我们将缺省分支推送到远端,并且新建一个 release version 的新分支推送到远端进行留存。
# 那第 7 步的话,我们发布一个 version 对应的 release。
on:
workflow_dispatch:
inputs:
version:
description: "Upstream release tag. Defaults to latest upstream tag."
required: false
type: string
concurrency:
group: welan-release
cancel-in-progress: false
permissions:
contents: write
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
GH_TOKEN: ${{ github.token }}
jobs:
release:
name: sync, validate, build, release
runs-on: ubuntu-24.04
defaults:
run:
shell: bash
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
fetch-depth: 0
token: ${{ github.token }}
- name: Configure git identity
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- name: Configure upstream remote
run: |
if git remote get-url upstream >/dev/null 2>&1; then
git remote set-url upstream https://github.com/anomalyco/opencode.git
else
git remote add upstream https://github.com/anomalyco/opencode.git
fi
- name: Resolve upstream tag
run: |
version="${{ inputs.version }}"
if [ -z "$version" ]; then
remote_tags="$(git ls-remote --tags --sort=-v:refname upstream 'refs/tags/v[0-9]*')"
version="$(printf '%s\n' "$remote_tags" | awk 'index($2, "^{}") == 0 { sub("refs/tags/", "", $2); print $2; exit }')"
fi
if [ -z "$version" ]; then
echo "No upstream tag found"
exit 1
fi
build_version="${version#v}"
echo "Using upstream tag: $version"
echo "Using build version: $build_version"
echo "RELEASE_TAG=$version" >> "$GITHUB_ENV"
echo "BUILD_VERSION=$build_version" >> "$GITHUB_ENV"
- name: Fetch branches and tags
run: |
git fetch origin welan:refs/remotes/origin/welan --tags
git fetch upstream "refs/tags/$RELEASE_TAG:refs/tags/$RELEASE_TAG"
git rev-parse --verify "refs/tags/$RELEASE_TAG^{commit}" >/dev/null
- name: Prepare dev from upstream tag
run: |
git checkout -B dev "$RELEASE_TAG"
- name: Rebase welan onto dev
id: rebase
continue-on-error: true
run: |
git checkout -B welan origin/welan
git rebase dev
- name: Print rebase conflict details
if: steps.rebase.outcome == 'failure'
run: |
conflicted_files="$(git diff --name-only --diff-filter=U || true)"
upstream_tag="$(git rev-parse "$RELEASE_TAG")"
origin_welan="$(git rev-parse origin/welan)"
current_head="$(git rev-parse HEAD)"
echo "::error::welan release $RELEASE_TAG hit a rebase conflict"
echo "Version: $RELEASE_TAG"
echo "Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
echo "Upstream tag: $RELEASE_TAG"
echo "Upstream tag SHA: ${upstream_tag}"
echo "origin/welan: ${origin_welan}"
echo "Current HEAD during conflict: ${current_head}"
echo
echo "Conflicted files:"
printf '%s\n' "$conflicted_files"
echo
echo "Git status:"
git status --short
echo
echo "Combined conflict diff:"
git diff --cc || true
echo
echo "Conflicted file contents:"
while IFS= read -r file; do
[ -n "$file" ] || continue
echo "::group::${file}"
if [ -f "$file" ] && grep -Iq . "$file"; then
cat "$file"
else
echo "Binary or missing conflicted file: $file"
fi
echo "::endgroup::"
done <<< "$conflicted_files"
git rebase --abort || true
exit 1
- name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "24"
- name: Setup Bun
uses: ./.github/actions/setup-bun
- name: Run run command module tests
working-directory: packages/opencode
timeout-minutes: 25
run: |
bun test --timeout 60000 test/cli/run/ --path-ignore-patterns 'run-process*.test.ts'
bun test --timeout 60000 --max-concurrency=1 test/cli/run/run-process-limit.test.ts
bun test --timeout 60000 --max-concurrency=1 test/cli/run/run-process.test.ts
env:
OPENCODE_EXPERIMENTAL_DISABLE_FILEWATCHER: "false"
- name: Build CLI binaries
run: OPENCODE_VERSION="$BUILD_VERSION" ./packages/opencode/script/build.ts
- name: Package selected release assets
run: |
asset_dir="/tmp/welan-release-assets"
rm -rf "$asset_dir"
mkdir -p "$asset_dir"
test -d packages/opencode/dist/opencode-darwin-arm64/bin
test -d packages/opencode/dist/opencode-linux-arm64/bin
test -d packages/opencode/dist/opencode-linux-x64/bin
(
cd packages/opencode/dist/opencode-darwin-arm64/bin
zip -r "$asset_dir/opencode-darwin-arm64.zip" .
)
(
cd packages/opencode/dist/opencode-linux-arm64/bin
tar -czf "$asset_dir/opencode-linux-arm64.tar.gz" .
)
(
cd packages/opencode/dist/opencode-linux-x64/bin
tar -czf "$asset_dir/opencode-linux-x64.tar.gz" .
)
ls -lh "$asset_dir"
- name: Push rebased welan
run: git push origin HEAD:welan --force-with-lease
- name: Push release archive branch
run: |
release_branch="release/$RELEASE_TAG"
git checkout -B "$release_branch"
git push origin "$release_branch" --force-with-lease
- name: Replace GitHub release
run: |
tag="$RELEASE_TAG"
target="$(git rev-parse HEAD)"
if gh release view "$tag" --repo "${{ github.repository }}" >/dev/null 2>&1; then
gh release delete "$tag" --repo "${{ github.repository }}" --yes
fi
if git ls-remote --exit-code --tags origin "refs/tags/$tag" >/dev/null 2>&1; then
git push origin ":refs/tags/$tag"
fi
git tag -f "$tag" "$target"
git push origin "refs/tags/$tag"
gh release create "$tag" \
/tmp/welan-release-assets/opencode-darwin-arm64.zip \
/tmp/welan-release-assets/opencode-linux-arm64.tar.gz \
/tmp/welan-release-assets/opencode-linux-x64.tar.gz \
--repo "${{ github.repository }}" \
--target "$target" \
--title "$tag" \
--notes "Fork release built from welan at ${target}."