fix(feishu): prevent concurrent initialization via promise singleton … #50
This file contains hidden or 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: Build, Publish & Release | |
| on: | |
| push: | |
| branches: [main] | |
| tags: ['v*.*.*'] | |
| permissions: | |
| contents: read | |
| id-token: write | |
| jobs: | |
| build-package: | |
| name: Build npm package | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: pnpm/action-setup@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: pnpm | |
| - run: pnpm install --frozen-lockfile | |
| - run: pnpm --filter ./apps/agent-inbox build | |
| - run: pnpm --filter ./apps/agent-inbox exec vp test run src/__tests__/packaging.test.ts src/__tests__/cli.test.ts src/__tests__/setup.test.ts | |
| - name: Pack npm tarball | |
| run: | | |
| mkdir -p artifacts | |
| pnpm --filter ./apps/agent-inbox pack --pack-destination artifacts | |
| - name: Smoke test npm tarball install | |
| run: | | |
| set -euo pipefail | |
| install_dir=$(mktemp -d) | |
| npm_cache_dir=$(mktemp -d) | |
| home_dir=$(mktemp -d) | |
| tarball=$(echo "$PWD"/artifacts/*.tgz) | |
| cd "$install_dir" | |
| npm init -y >/dev/null 2>&1 | |
| NPM_CONFIG_CACHE="$npm_cache_dir" npm install "$tarball" | |
| INSTALL_DIR="$install_dir" HOME_DIR="$home_dir" python3 <<'PY' | |
| import os | |
| import pty | |
| import select | |
| import subprocess | |
| import sys | |
| import time | |
| env = dict(os.environ) | |
| env["HOME"] = env["HOME_DIR"] | |
| master_fd, slave_fd = pty.openpty() | |
| process = None | |
| chunks = [] | |
| markers = ("No platforms configured yet", "Which platform to configure", "Agent Inbox") | |
| try: | |
| process = subprocess.Popen( | |
| ["./node_modules/.bin/agent-inbox"], | |
| cwd=env["INSTALL_DIR"], | |
| env=env, | |
| stdin=slave_fd, | |
| stdout=slave_fd, | |
| stderr=slave_fd, | |
| ) | |
| os.close(slave_fd) | |
| deadline = time.time() + 5 | |
| while time.time() < deadline: | |
| ready, _, _ = select.select([master_fd], [], [], 0.2) | |
| if master_fd not in ready: | |
| continue | |
| data = os.read(master_fd, 8192) | |
| if not data: | |
| break | |
| chunks.append(data) | |
| output = b"".join(chunks).decode("utf-8", errors="replace") | |
| if any(marker in output for marker in markers): | |
| break | |
| finally: | |
| try: | |
| os.close(slave_fd) | |
| except OSError: | |
| pass | |
| try: | |
| if process is not None: | |
| process.terminate() | |
| process.wait(timeout=1) | |
| except Exception: | |
| try: | |
| if process is not None: | |
| process.kill() | |
| process.wait(timeout=1) | |
| except Exception: | |
| pass | |
| try: | |
| os.close(master_fd) | |
| except OSError: | |
| pass | |
| output = b"".join(chunks).decode("utf-8", errors="replace") | |
| print(output) | |
| if not any( | |
| token in output | |
| for token in ("No platforms configured yet", "Which platform to configure", "Agent Inbox") | |
| ): | |
| sys.exit(1) | |
| PY | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: agent-inbox-npm-package | |
| path: artifacts/*.tgz | |
| publish-npm: | |
| name: Publish npm package | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| needs: build-package | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: pnpm/action-setup@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: pnpm | |
| registry-url: https://registry.npmjs.org | |
| - run: pnpm install --frozen-lockfile | |
| - id: package-meta | |
| name: Validate package metadata | |
| run: | | |
| package_name=$(node -p "JSON.parse(require('node:fs').readFileSync('apps/agent-inbox/package.json', 'utf8')).name") | |
| package_version=$(node -p "JSON.parse(require('node:fs').readFileSync('apps/agent-inbox/package.json', 'utf8')).version") | |
| tag_version="${GITHUB_REF_NAME#v}" | |
| echo "package_name=$package_name" >> "$GITHUB_OUTPUT" | |
| echo "package_version=$package_version" >> "$GITHUB_OUTPUT" | |
| if [[ "$package_name" != "@doctorwu/agent-inbox" ]]; then | |
| echo "Expected package name @doctorwu/agent-inbox, got $package_name" >&2 | |
| exit 1 | |
| fi | |
| if [[ "$package_version" != "$tag_version" ]]; then | |
| echo "Tag version $tag_version does not match apps/agent-inbox/package.json version $package_version" >&2 | |
| exit 1 | |
| fi | |
| - name: Publish package | |
| run: pnpm --filter ./apps/agent-inbox publish --access public --provenance --no-git-checks | |
| create-release: | |
| name: Create GitHub Release | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| needs: [build-package, publish-npm] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Fetch tags | |
| run: git fetch --force --tags | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: agent-inbox-npm-package | |
| path: artifacts | |
| - name: Generate release notes | |
| env: | |
| TAG_NAME: ${{ github.ref_name }} | |
| run: | | |
| set -euo pipefail | |
| current_tag="$TAG_NAME" | |
| previous_tag=$(git tag -l 'v*' --sort=-version:refname | grep -Fxv "$current_tag" | head -n1 || true) | |
| package_version="${current_tag#v}" | |
| changelog_file=$(mktemp) | |
| if [[ -n "$previous_tag" ]]; then | |
| git log --no-merges --pretty='- %s (%h)' "${previous_tag}..${current_tag}" > "$changelog_file" | |
| else | |
| git log --no-merges --pretty='- %s (%h)' "$current_tag" > "$changelog_file" | |
| fi | |
| if [[ ! -s "$changelog_file" ]]; then | |
| printf -- '- No changes captured between tags.\n' > "$changelog_file" | |
| fi | |
| { | |
| echo "# agent-inbox ${current_tag}" | |
| echo | |
| echo "- Version: \`${package_version}\`" | |
| if [[ -n "$previous_tag" ]]; then | |
| echo "- Changes since: \`${previous_tag}\`" | |
| else | |
| echo "- Changes since: initial release" | |
| fi | |
| echo | |
| echo "## Changelog" | |
| echo | |
| cat "$changelog_file" | |
| } > release-notes.md | |
| - uses: softprops/action-gh-release@v2 | |
| with: | |
| name: agent-inbox ${{ github.ref_name }} | |
| body_path: release-notes.md | |
| files: artifacts/*.tgz |