Skip to content

feat: unified build and publish scripts with tag format fix#13

Merged
wysaid merged 2 commits intomasterfrom
feature/unified-build-publish-scripts
Jan 31, 2026
Merged

feat: unified build and publish scripts with tag format fix#13
wysaid merged 2 commits intomasterfrom
feature/unified-build-publish-scripts

Conversation

@wysaid
Copy link
Collaborator

@wysaid wysaid commented Jan 31, 2026

概述

统一构建和发布脚本,修复了版本标签格式问题。

主要变更

  • 创建 tasks.sh 作为统一的脚本,处理所有构建/发布任务
  • build.shpublish.sh 转换为包装脚本以保持向后兼容
  • 修复 release.yml 标签格式,使用 'v' 前缀 (v1.0.3 而不是 1.0.3)
  • 支持稳定版本标签 (v1.0.3) 和预发布标签 (v1.0.3-pre)
  • 统一本地脚本和 GitHub 工作流中的标签格式

优势

  • 代码重用和可维护性(单一事实来源)
  • 本地脚本和 CI/CD 之间标签格式一致
  • 向后兼容(旧脚本仍能工作)
  • 更好的用户体验(集中的帮助和选项)

变更文件

  • .github/workflows/release.yml: 修改工作流配置
  • build.sh: 精简,转为包装脚本
  • publish.sh: 添加新的功能
  • tasks.sh: 新增统一脚本(509 行代码)

总计: 4 个文件改动,527 行新增,48 行删除

Summary by CodeRabbit

发布说明

  • New Features

    • 添加统一的任务运行器,提供构建与发布一体化命令行体验,并保留旧入口的兼容包装。
  • Chores

    • 统一并改进了发布标签处理(强制使用前缀 v),发布验证和版本提取更加稳健。
  • Refactor

    • 简化并重构构建/发布流程,改善可维护性与用户交互提示。

✏️ Tip: You can customize this high-level summary in your review settings.

- Create tasks.sh as unified script for build/publish tasks
- Convert build.sh and publish.sh to wrapper scripts for backward compatibility
- Fix release.yml tag format to use 'v' prefix (v1.0.3 instead of 1.0.3)
- Support both stable (v1.0.3) and pre-release (v1.0.3-pre) tags
- Unified tag format across scripts and GitHub workflows

Benefits:
- Code reuse and maintainability (single source of truth)
- Consistent tag format between local scripts and CI/CD
- Backward compatible (old scripts still work)
- Better UX with centralized help and options
Copilot AI review requested due to automatic review settings January 31, 2026 18:37
@coderabbitai
Copy link

coderabbitai bot commented Jan 31, 2026

演练

此变更重构了发布工作流,引入统一的任务运行器脚本(tasks.sh)来处理构建与发布,同时将现有脚本(build.sh 与新增的 publish.sh)改为向后兼容的包装器,并更新 GitHub Actions 发布流程以统一使用 v 前缀的标签格式。

变更

内聚组 / 文件 摘要
发布工作流程配置
.github/workflows/release.yml
调整标签处理逻辑以始终使用 v 前缀(例如 v1.2.3);更新标签格式验证(稳定与预发布都强制 ^v...);从标签中剥离前导 v 以提取数字版本。
向后兼容包装器脚本
build.sh
publish.sh
build.sh 被简化为轻量包装器,切换到脚本目录后立即 exec ./tasks.sh --build "$@";新增 publish.sh,作为 ./tasks.sh --publish "$@" 的向后兼容包装器。
统一任务运行器
tasks.sh
新增大型 Bash 任务运行器,支持 buildpublish 两条主流程;包含命令行解析、交互提示、彩色状态输出、依赖检查/安装、构建(npm install、清理、vsce 打包)以及发布(未提交检查、版本提取、标签命名/校验、远程/分支一致性检查、强制覆盖选项、干运行支持)与最终推送逻辑。

预计代码审查工作量

🎯 4 (复杂) | ⏱️ ~50 分钟

🐰✨ 一条兔子的歌谣 ✨
旧脚本绕着圈跑忙,
现在统一到任务箱,
v 字领队出发忙,
构建发布步调长,
包装兼容笑嘻嘻!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 61.54% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确总结了主要变更:统一构建发布脚本并修复标签格式。内容与变更集直接相关,涵盖了 PR 的核心目标。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/unified-build-publish-scripts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@wysaid
Copy link
Collaborator Author

wysaid commented Jan 31, 2026

@Auggie review

@augmentcode
Copy link

augmentcode bot commented Jan 31, 2026

🤖 Augment PR Summary

Summary: This PR unifies local build/publish automation and aligns CI release tags with a v-prefixed semantic version format.

Changes:

  • Updates .github/workflows/release.yml to emit and validate tags like v1.0.3 / v1.0.3-*, and extracts the numeric version after stripping the v prefix.
  • Introduces a new unified tasks.sh script that implements build/publish flows with prompts, dry-run, pre-release, force, and skip-install options.
  • Refactors build.sh into a thin wrapper that delegates to tasks.sh --build for backward compatibility.
  • Adds publish.sh as a thin wrapper that delegates to tasks.sh --publish.

Technical Notes: The tag prefix change is intended to keep local scripts and GitHub workflow behavior consistent, supporting both stable and pre-release tags under a single convention.

🤖 Was this summary useful? React with 👍 or 👎

Copy link

@augmentcode augmentcode bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 3 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

tasks.sh Outdated
SKIP_INSTALL=false

show_help() {
echo "Usage: $0 <TASK> [OPTIONS]"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The help text says Usage: $0 <TASK> [OPTIONS], but the script actually requires flags (--build/--publish) and treats positional tasks as unknown options, which could confuse users.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.


# Check for uncommitted changes
info "Checking for uncommitted changes..."
if ! git diff-index --quiet HEAD -- 2>/dev/null; then
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cleanliness check uses git diff-index, which ignores untracked files; an untracked file that isn’t excluded by .vscodeignore could still be packaged/published in the VSIX.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

if [ "$DRY_RUN" = false ]; then
info "Checking if tag ${TAG_NAME} already exists..."

if git ls-remote --tags origin 2>/dev/null | grep -q "refs/tags/${TAG_NAME}$"; then
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tag existence is checked only on the remote; if the tag already exists locally (e.g., after a previous failed run), the script can publish to the marketplace and then fail when creating the tag, leaving the release half-complete.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Copy link

@augmentcode augmentcode bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 3 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

tasks.sh Outdated
SKIP_INSTALL=false

show_help() {
echo "Usage: $0 <TASK> [OPTIONS]"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The help text says Usage: $0 <TASK> [OPTIONS], but the argument parser only accepts task flags (--build/--publish), so a user following the usage line (e.g., ./tasks.sh build) will hit the “Unknown option” path.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

tasks.sh Outdated

# Get default branch name
get_default_branch() {
git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "master"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In get_default_branch, the || echo "master" fallback likely never runs because the pipeline’s exit status is from sed (usually 0) even when git symbolic-ref fails, so DEFAULT_BRANCH can become empty and break the branch check logic.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

tasks.sh Outdated

# Build
info "Building extension..."
VSIX_FILE=$(do_build)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VSIX_FILE=$(do_build) captures all stdout from do_build (including [INFO]/[SUCCESS] lines), so build output is hidden during publish and the captured value can be more than just the filename until it’s overwritten by the subsequent ls.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR unifies local build/publish automation into a single tasks.sh entrypoint while aligning GitHub Actions release tag parsing with a v-prefixed tag format.

Changes:

  • Added tasks.sh to centralize build/publish logic (including tag formatting for stable vs pre-release).
  • Converted build.sh and publish.sh into thin wrapper scripts for backward compatibility.
  • Updated .github/workflows/release.yml to expect and generate vX.Y.Z-style tags and correctly extract versions from them.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

File Description
tasks.sh New unified build/publish script; introduces tag-format logic and CLI UX improvements.
build.sh Now delegates to tasks.sh --build to preserve existing entrypoint.
publish.sh Now delegates to tasks.sh --publish to preserve existing entrypoint.
.github/workflows/release.yml Updates tag generation/validation/extraction to use v-prefixed tags consistently.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +25 to +31
show_help() {
echo "Usage: $0 <TASK> [OPTIONS]"
echo ""
echo "Tasks:"
echo " -b, --build Build the extension (create .vsix file)"
echo " -p, --publish Build and publish to VS Code Marketplace"
echo ""
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The help text says Usage: $0 <TASK> [OPTIONS], but the script doesn’t accept a positional TASK (only -b/--build and -p/--publish). Update the usage string to match the actual CLI, or add support for positional build|publish to avoid confusing users.

Copilot uses AI. Check for mistakes.
Comment on lines +249 to +252
# Check for uncommitted changes
info "Checking for uncommitted changes..."
if ! git diff-index --quiet HEAD -- 2>/dev/null; then
MODIFIED_FILES=$(git diff-index --name-only HEAD --)
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

git diff-index --quiet only checks tracked changes and ignores untracked files, but the script reports Working directory is clean and may proceed even if untracked files exist. Consider using git status --porcelain (or an explicit untracked check) so the cleanliness check matches the message and intended safety gate.

Suggested change
# Check for uncommitted changes
info "Checking for uncommitted changes..."
if ! git diff-index --quiet HEAD -- 2>/dev/null; then
MODIFIED_FILES=$(git diff-index --name-only HEAD --)
# Check for uncommitted changes (including untracked files)
info "Checking for uncommitted changes..."
STATUS_OUTPUT=$(git status --porcelain 2>/dev/null || true)
if [ -n "$STATUS_OUTPUT" ]; then
MODIFIED_FILES=$(echo "$STATUS_OUTPUT" | sed 's/^.. //')

Copilot uses AI. Check for mistakes.
Comment on lines +314 to +316
git push origin ":refs/tags/${TAG_NAME}" || true
git tag -d "${TAG_NAME}" 2>/dev/null || true
success "Remote tag deleted"
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the force-delete path, both tag deletion commands are || true but the script still prints Remote tag deleted unconditionally. This can report success even when deletion fails (e.g., permissions/network). Capture and check the return codes (or conditionally print a warning) so the user gets accurate feedback.

Suggested change
git push origin ":refs/tags/${TAG_NAME}" || true
git tag -d "${TAG_NAME}" 2>/dev/null || true
success "Remote tag deleted"
REMOTE_DELETED=false
LOCAL_DELETED=false
if git push origin ":refs/tags/${TAG_NAME}"; then
REMOTE_DELETED=true
else
warning "Failed to delete remote tag ${TAG_NAME} from origin"
fi
if git tag -d "${TAG_NAME}" 2>/dev/null; then
LOCAL_DELETED=true
else
warning "Failed to delete local tag ${TAG_NAME}"
fi
if [ "$REMOTE_DELETED" = true ] && [ "$LOCAL_DELETED" = true ]; then
success "Remote tag deleted"
else
warning "Tag deletion was not fully successful; please verify tag ${TAG_NAME} locally and on origin."
fi

Copilot uses AI. Check for mistakes.
tasks.sh Outdated

# Build
info "Building extension..."
VSIX_FILE=$(do_build)
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VSIX_FILE=$(do_build) captures all stdout from do_build (including [INFO]/[SUCCESS] lines), and then the variable is immediately overwritten by re-running ls. This suppresses build output during publish and makes the first assignment redundant. Prefer calling do_build normally (no capture) and then locate the VSIX, or redirect do_build logs to stderr and have it print only the filename on stdout.

Suggested change
VSIX_FILE=$(do_build)
do_build

Copilot uses AI. Check for mistakes.

# Get version from package.json
get_version() {
grep -o '"version": *"[^"]*"' package.json | sed 's/"version": *"\(.*\)"/\1/'
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_version parses package.json via grep|sed, which is brittle if formatting changes or if another "version" key appears in a different context. Since Node is already a required dependency (and the workflow uses it), consider using node -p "require('./package.json').version" here for a more robust single source of truth.

Suggested change
grep -o '"version": *"[^"]*"' package.json | sed 's/"version": *"\(.*\)"/\1/'
node -p "require('./package.json').version"

Copilot uses AI. Check for mistakes.

# Check npm
if ! command -v npm &>/dev/null; then
error "npm is not found. It should come with Node.js."
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regression vs the previous build.sh: after attempting to install Node via apt/yum, the script errors out if npm is missing, but on Debian/Ubuntu nodejs often does not include npm. Consider attempting to install npm via install_util npm (or a distro-appropriate package) when npm isn’t found, and adjust the error message accordingly.

Suggested change
error "npm is not found. It should come with Node.js."
warning "npm is not found. Attempting to install..."
install_util npm || true
fi
if ! command -v npm &>/dev/null; then
error "npm is not installed. On some systems, Node.js does not include npm. Please install npm via your package manager and re-run this script."

Copilot uses AI. Check for mistakes.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@build.sh`:
- Around line 5-6: Verify the script exits when directory change fails: make the
cd "$(dirname "$0")" call guarded so the script does not continue if it fails
(e.g., test the return and exit non‑zero or print an error), ensuring the
subsequent exec ./tasks.sh --build "$@" is only run after a successful cd;
update the build.sh around the cd and exec lines to perform that check (use a
conditional or || exit) so tasks.sh is not invoked from the wrong directory.

In `@publish.sh`:
- Around line 5-6: The script currently runs cd "$(dirname "$0")" without
handling failure, so exec ./tasks.sh --publish "$@" may run from the wrong
directory; update publish.sh to detect and handle a failed directory change
(e.g., test the result of cd "$(dirname "$0")" and exit with a non-zero status
if it fails) before calling exec ./tasks.sh --publish "$@"; ensure the check
references the existing commands (cd "$(dirname "$0")" and exec ./tasks.sh
--publish "$@") so the script aborts early on cd failure.

In `@tasks.sh`:
- Around line 412-457: The post-build flow can miss lockfile changes introduced
by do_build() (which runs npm install), so before creating or tagging (where
TAG_NAME and git tag -a are used) add a workspace validation step after
VSIX_FILE is determined: run a git status --porcelain check (or equivalent) that
ignores the generated .vsix (VSIX_FILE) and fails if any other tracked files
changed (e.g., package-lock.json, pnpm-lock.yaml); if changes exist, abort with
an error and instructions to commit or re-run with CI-safe install, or
alternatively modify do_build() to use npm ci instead of npm install to prevent
modifying lockfiles. Ensure this check runs before the git tag creation and
ask_yes_no push prompt.
🧹 Nitpick comments (1)
tasks.sh (1)

141-144: get_version 建议用 Node 解析 JSON

grep/sed 依赖格式细节,改为 Node 解析更稳健,且脚本已要求安装 Node。

建议修复
-get_version() {
-    grep -o '"version": *"[^"]*"' package.json | sed 's/"version": *"\(.*\)"/\1/'
-}
+get_version() {
+    node -p "require('./package.json').version"
+}

Comment on lines +412 to +457
# Build
info "Building extension..."
VSIX_FILE=$(do_build)
VSIX_FILE=$(ls -t *.vsix 2>/dev/null | head -1)

if [ -z "$VSIX_FILE" ]; then
error "Build failed - no .vsix file found"
exit 1
fi

success "Built: ${VSIX_FILE}"

# Publish to marketplace
if [ "$DRY_RUN" = false ]; then
info "Publishing to VS Code Marketplace..."

if [ "$PRE_RELEASE" = true ]; then
vsce publish --pre-release --packagePath "$VSIX_FILE"
else
vsce publish --packagePath "$VSIX_FILE"
fi

success "Published to VS Code Marketplace!"
else
info "[DRY-RUN] Would publish: vsce publish $([ "$PRE_RELEASE" = true ] && echo "--pre-release ")--packagePath ${VSIX_FILE}"
fi

# Create and push tag
if [ "$DRY_RUN" = false ]; then
if [ "$SKIP_TAG" = true ]; then
info "Skipping tag creation (already exists)"
else
info "Creating tag ${TAG_NAME}..."
git tag -a "${TAG_NAME}" -m "Release ege v${VERSION}$([ "$PRE_RELEASE" = true ] && echo " (pre-release)")"
success "Tag created: ${TAG_NAME}"

if ask_yes_no "Push tag to remote?"; then
git push origin "${TAG_NAME}"
success "Tag pushed to remote"
else
warning "Tag not pushed. Run: git push origin ${TAG_NAME}"
fi
fi
else
info "[DRY-RUN] Would create and push tag: ${TAG_NAME}"
fi
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n tasks.sh | head -50

Repository: x-ege/ege-vscode-plugin

Length of output: 1826


🏁 Script executed:

git ls-files | grep -E "tasks\.sh|package-lock\.json|\.npmrc|\.nvmrc" | head -20

Repository: x-ege/ege-vscode-plugin

Length of output: 75


🏁 Script executed:

rg "do_build" -A 30 tasks.sh

Repository: x-ege/ege-vscode-plugin

Length of output: 1918


🏁 Script executed:

rg "npm install" tasks.sh

Repository: x-ege/ege-vscode-plugin

Length of output: 309


🏁 Script executed:

rg "git status|git diff|porcelain" tasks.sh -B 5 -A 5

Repository: x-ege/ege-vscode-plugin

Length of output: 498


🏁 Script executed:

rg "check_git_status|validate" tasks.sh -A 10

Repository: x-ege/ege-vscode-plugin

Length of output: 49


🏁 Script executed:

rg "publish_main\|do_publish" tasks.sh -A 50 | head -100

Repository: x-ege/ege-vscode-plugin

Length of output: 49


🏁 Script executed:

fd "package-lock.json" -o "pnpm-lock.yaml" -o "yarn.lock"

Repository: x-ege/ege-vscode-plugin

Length of output: 214


🏁 Script executed:

rg "Check for uncommitted changes" tasks.sh -B 5 -A 30

Repository: x-ege/ege-vscode-plugin

Length of output: 1410


🏁 Script executed:

git ls-files | grep -i "package-lock\|pnpm-lock\|yarn.lock"

Repository: x-ege/ege-vscode-plugin

Length of output: 49


🏁 Script executed:

rg "git status|git diff" tasks.sh -B 3 -A 8

Repository: x-ege/ege-vscode-plugin

Length of output: 673


🏁 Script executed:

rg "do_publish" tasks.sh -A 80 | head -120

Repository: x-ege/ege-vscode-plugin

Length of output: 3078


🏁 Script executed:

cat -n tasks.sh | sed -n '200,450p'

Repository: x-ege/ege-vscode-plugin

Length of output: 10290


构建后需再次校验工作区状态,防止锁文件修改导致发布产物与标签不一致

虽然发布前会检查未提交的更改(第 250-281 行),但该检查发生在 npm install 之前。do_build() 内的 npm install 调用(第 207 行)可能会修改 package-lock.jsonpnpm-lock.yaml。构建完成后直接创建标签(第 445 行),工作区的锁文件变更不会被重新验证,导致标签指向的提交与实际构建产物使用的依赖版本不一致。

建议在构建完成后添加工作区验证,确保 .vsix 以外的跟踪文件未被修改,或改用 npm ci 代替 npm install 以保持锁文件不变。

建议修复(构建后再校验)
    VSIX_FILE=$(do_build)
    VSIX_FILE=$(ls -t *.vsix 2>/dev/null | head -1)

+   # Ensure build didn't modify tracked files (e.g., lockfiles)
+   if git status --porcelain | grep -vE '^\?\? .*\.vsix$' | grep -q .; then
+       error "Working tree changed during build (e.g., lockfile updates). Please commit or stash before publishing."
+       exit 1
+   fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Build
info "Building extension..."
VSIX_FILE=$(do_build)
VSIX_FILE=$(ls -t *.vsix 2>/dev/null | head -1)
if [ -z "$VSIX_FILE" ]; then
error "Build failed - no .vsix file found"
exit 1
fi
success "Built: ${VSIX_FILE}"
# Publish to marketplace
if [ "$DRY_RUN" = false ]; then
info "Publishing to VS Code Marketplace..."
if [ "$PRE_RELEASE" = true ]; then
vsce publish --pre-release --packagePath "$VSIX_FILE"
else
vsce publish --packagePath "$VSIX_FILE"
fi
success "Published to VS Code Marketplace!"
else
info "[DRY-RUN] Would publish: vsce publish $([ "$PRE_RELEASE" = true ] && echo "--pre-release ")--packagePath ${VSIX_FILE}"
fi
# Create and push tag
if [ "$DRY_RUN" = false ]; then
if [ "$SKIP_TAG" = true ]; then
info "Skipping tag creation (already exists)"
else
info "Creating tag ${TAG_NAME}..."
git tag -a "${TAG_NAME}" -m "Release ege v${VERSION}$([ "$PRE_RELEASE" = true ] && echo " (pre-release)")"
success "Tag created: ${TAG_NAME}"
if ask_yes_no "Push tag to remote?"; then
git push origin "${TAG_NAME}"
success "Tag pushed to remote"
else
warning "Tag not pushed. Run: git push origin ${TAG_NAME}"
fi
fi
else
info "[DRY-RUN] Would create and push tag: ${TAG_NAME}"
fi
# Build
info "Building extension..."
VSIX_FILE=$(do_build)
VSIX_FILE=$(ls -t *.vsix 2>/dev/null | head -1)
if [ -z "$VSIX_FILE" ]; then
error "Build failed - no .vsix file found"
exit 1
fi
# Ensure build didn't modify tracked files (e.g., lockfiles)
if git status --porcelain | grep -vE '^\?\? .*\.vsix$' | grep -q .; then
error "Working tree changed during build (e.g., lockfile updates). Please commit or stash before publishing."
exit 1
fi
success "Built: ${VSIX_FILE}"
# Publish to marketplace
if [ "$DRY_RUN" = false ]; then
info "Publishing to VS Code Marketplace..."
if [ "$PRE_RELEASE" = true ]; then
vsce publish --pre-release --packagePath "$VSIX_FILE"
else
vsce publish --packagePath "$VSIX_FILE"
fi
success "Published to VS Code Marketplace!"
else
info "[DRY-RUN] Would publish: vsce publish $([ "$PRE_RELEASE" = true ] && echo "--pre-release ")--packagePath ${VSIX_FILE}"
fi
# Create and push tag
if [ "$DRY_RUN" = false ]; then
if [ "$SKIP_TAG" = true ]; then
info "Skipping tag creation (already exists)"
else
info "Creating tag ${TAG_NAME}..."
git tag -a "${TAG_NAME}" -m "Release ege v${VERSION}$([ "$PRE_RELEASE" = true ] && echo " (pre-release)")"
success "Tag created: ${TAG_NAME}"
if ask_yes_no "Push tag to remote?"; then
git push origin "${TAG_NAME}"
success "Tag pushed to remote"
else
warning "Tag not pushed. Run: git push origin ${TAG_NAME}"
fi
fi
else
info "[DRY-RUN] Would create and push tag: ${TAG_NAME}"
fi
🤖 Prompt for AI Agents
In `@tasks.sh` around lines 412 - 457, The post-build flow can miss lockfile
changes introduced by do_build() (which runs npm install), so before creating or
tagging (where TAG_NAME and git tag -a are used) add a workspace validation step
after VSIX_FILE is determined: run a git status --porcelain check (or
equivalent) that ignores the generated .vsix (VSIX_FILE) and fails if any other
tracked files changed (e.g., package-lock.json, pnpm-lock.yaml); if changes
exist, abort with an error and instructions to commit or re-run with CI-safe
install, or alternatively modify do_build() to use npm ci instead of npm install
to prevent modifying lockfiles. Ensure this check runs before the git tag
creation and ask_yes_no push prompt.

- Fix Usage text: clarify that tasks use flags, not positional arguments
- Fix get_default_branch: ensure fallback to 'master' when result is empty
- Fix VSIX_FILE capture: call do_build directly to show output
- Add cd failure protection to build.sh and publish.sh (|| exit 1)
@wysaid wysaid merged commit b97d188 into master Jan 31, 2026
3 checks passed
@wysaid wysaid deleted the feature/unified-build-publish-scripts branch January 31, 2026 18:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants