Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 29 additions & 5 deletions .github/workflows/build-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
- 'docs/**'
- '.gitignore'
- 'LICENSE'
pull_request:
pull_request:
branches: [ main ]
paths-ignore:
- 'docs/**'
Expand Down Expand Up @@ -39,6 +39,9 @@ jobs:
- os: ubuntu-24.04
arch: x86_64
platform: linux
- os: ubuntu-24.04-arm
arch: arm64
platform: linux
- os: macos-13
arch: x86_64
platform: darwin
Expand Down Expand Up @@ -90,7 +93,8 @@ jobs:

- name: Run smoke tests
env:
GITHUB_APM_PAT: ${{ secrets.GH_CLI_PAT }} # Primary: APM module access (FG PAT)
GITHUB_TOKEN: ${{ secrets.GH_MODELS_PAT }} # Models access
GITHUB_APM_PAT: ${{ secrets.GH_CLI_PAT }} # APM module access
run: uv run pytest tests/integration/test_runtime_smoke.py -v

# Build binaries
Expand All @@ -104,6 +108,10 @@ jobs:
platform: linux
arch: x86_64
binary_name: apm-linux-x86_64
- os: ubuntu-24.04-arm
platform: linux
arch: arm64
binary_name: apm-linux-arm64
- os: macos-13
platform: darwin
arch: x86_64
Expand Down Expand Up @@ -179,6 +187,10 @@ jobs:
arch: x86_64
platform: linux
binary_name: apm-linux-x86_64
- os: ubuntu-24.04-arm
arch: arm64
platform: linux
binary_name: apm-linux-arm64
- os: macos-13
arch: x86_64
platform: darwin
Expand Down Expand Up @@ -250,6 +262,10 @@ jobs:
arch: x86_64
platform: linux
binary_name: apm-linux-x86_64
- os: ubuntu-24.04-arm
arch: arm64
platform: linux
binary_name: apm-linux-arm64
- os: macos-13
arch: x86_64
platform: darwin
Expand Down Expand Up @@ -309,7 +325,7 @@ jobs:

- name: Run release validation tests
env:
APM_E2E_TESTS: "1" # Avoids interactive prompts for MCP env values with apm install
APM_E2E_TESTS: "1" # Avoids interactive prompts for MCP env values with apm install
GITHUB_TOKEN: ${{ secrets.GH_MODELS_PAT }}
GITHUB_APM_PAT: ${{ secrets.GH_CLI_PAT }} # Primary: APM module access
run: |
Expand Down Expand Up @@ -345,7 +361,7 @@ jobs:

# Create tar.gz archives from directory structure for release and Homebrew
cd dist
for binary in apm-linux-x86_64 apm-darwin-x86_64 apm-darwin-arm64; do
for binary in apm-linux-x86_64 apm-linux-arm64 apm-darwin-x86_64 apm-darwin-arm64; do
# With artifacts containing both scripts and dist/, the binary is in artifact/dist/binary/
artifact_dir="${binary}"
binary_dir="${artifact_dir}/dist/${binary}"
Expand Down Expand Up @@ -402,6 +418,8 @@ jobs:
files: |
./dist/apm-linux-x86_64.tar.gz
./dist/apm-linux-x86_64.tar.gz.sha256
./dist/apm-linux-arm64.tar.gz
./dist/apm-linux-arm64.tar.gz.sha256
./dist/apm-darwin-x86_64.tar.gz
./dist/apm-darwin-x86_64.tar.gz.sha256
./dist/apm-darwin-arm64.tar.gz
Expand Down Expand Up @@ -467,19 +485,24 @@ jobs:
"https://github.com/${{ github.repository }}/releases/download/$RELEASE_TAG/apm-darwin-x86_64.tar.gz.sha256"
curl -L -o apm-linux-x86_64.tar.gz.sha256 \
"https://github.com/${{ github.repository }}/releases/download/$RELEASE_TAG/apm-linux-x86_64.tar.gz.sha256"
curl -L -o apm-linux-arm64.tar.gz.sha256 \
"https://github.com/${{ github.repository }}/releases/download/$RELEASE_TAG/apm-linux-arm64.tar.gz.sha256"

# Extract SHA256 checksums
DARWIN_ARM64_SHA=$(cat apm-darwin-arm64.tar.gz.sha256 | cut -d' ' -f1)
DARWIN_X86_64_SHA=$(cat apm-darwin-x86_64.tar.gz.sha256 | cut -d' ' -f1)
LINUX_X86_64_SHA=$(cat apm-linux-x86_64.tar.gz.sha256 | cut -d' ' -f1)
LINUX_ARM64_SHA=$(cat apm-linux-arm64.tar.gz.sha256 | cut -d' ' -f1)

echo "darwin-arm64-sha=$DARWIN_ARM64_SHA" >> $GITHUB_OUTPUT
echo "darwin-x86_64-sha=$DARWIN_X86_64_SHA" >> $GITHUB_OUTPUT
echo "linux-x86_64-sha=$LINUX_X86_64_SHA" >> $GITHUB_OUTPUT
echo "linux-arm64-sha=$LINUX_ARM64_SHA" >> $GITHUB_OUTPUT

echo "Darwin ARM64 SHA: $DARWIN_ARM64_SHA"
echo "Darwin x86_64 SHA: $DARWIN_X86_64_SHA"
echo "Linux x86_64 SHA: $LINUX_X86_64_SHA"
echo "Linux ARM64 SHA: $LINUX_ARM64_SHA"

- name: Trigger Homebrew tap repository update
uses: peter-evans/repository-dispatch@v3
Expand All @@ -497,6 +520,7 @@ jobs:
"checksums": {
"darwin_arm64": "${{ steps.checksums.outputs.darwin-arm64-sha }}",
"darwin_x86_64": "${{ steps.checksums.outputs.darwin-x86_64-sha }}",
"linux_x86_64": "${{ steps.checksums.outputs.linux-x86_64-sha }}"
"linux_x86_64": "${{ steps.checksums.outputs.linux-x86_64-sha }}",
"linux_arm64": "${{ steps.checksums.outputs.linux-arm64-sha }}"
Copy link
Collaborator

Choose a reason for hiding this comment

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

We need to update the homebrew formula at danielmeppiel/homebrew-apm#5 so that it accepts the new binary and processes installation correctly

}
}
20 changes: 19 additions & 1 deletion scripts/github-token-helper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,25 @@ setup_github_tokens() {
echo -e "${BLUE}Setting up GitHub tokens...${NC}"
fi

# DEBUG: Show all GitHub-related environment variables
echo -e "${YELLOW}🔍 DEBUG: GitHub token environment analysis:${NC}"
echo " GITHUB_TOKEN: ${GITHUB_TOKEN:+SET(${#GITHUB_TOKEN} chars)}${GITHUB_TOKEN:-UNSET}"
echo " GITHUB_APM_PAT: ${GITHUB_APM_PAT:+SET(${#GITHUB_APM_PAT} chars)}${GITHUB_APM_PAT:-UNSET}"
echo " GH_MODELS_PAT: ${GH_MODELS_PAT:+SET(${#GH_MODELS_PAT} chars)}${GH_MODELS_PAT:-UNSET}"
echo " GH_CLI_PAT: ${GH_CLI_PAT:+SET(${#GH_CLI_PAT} chars)}${GH_CLI_PAT:-UNSET}"
echo " GH_PKG_PAT: ${GH_PKG_PAT:+SET(${#GH_PKG_PAT} chars)}${GH_PKG_PAT:-UNSET}"
echo " CI environment: ${CI:-UNSET}"
echo " GITHUB_ACTIONS: ${GITHUB_ACTIONS:-UNSET}"

# CRITICAL: Preserve existing GITHUB_TOKEN if set (for Models access)
local preserve_github_token=""
if [[ -n "${GITHUB_TOKEN:-}" ]]; then
preserve_github_token="$GITHUB_TOKEN"
if [[ "$quiet_mode" != "true" ]]; then
echo -e "${GREEN}✓ Preserving existing GITHUB_TOKEN for Models access${NC}"
echo -e "${GREEN}✓ Preserving existing GITHUB_TOKEN for Models access (${#GITHUB_TOKEN} chars)${NC}"
fi
else
echo -e "${YELLOW}⚠️ No GITHUB_TOKEN found initially${NC}"
fi

# 2. Setup APM module access
Expand Down Expand Up @@ -61,6 +73,12 @@ setup_github_tokens() {
export GITHUB_MODELS_KEY="${GITHUB_TOKEN}"
fi

# DEBUG: Show final token state
echo -e "${YELLOW}🔍 DEBUG: Final token configuration:${NC}"
echo " GITHUB_TOKEN: ${GITHUB_TOKEN:+SET(${#GITHUB_TOKEN} chars)}${GITHUB_TOKEN:-UNSET}"
echo " GITHUB_APM_PAT: ${GITHUB_APM_PAT:+SET(${#GITHUB_APM_PAT} chars)}${GITHUB_APM_PAT:-UNSET}"
echo " GITHUB_MODELS_KEY: ${GITHUB_MODELS_KEY:+SET(${#GITHUB_MODELS_KEY} chars)}${GITHUB_MODELS_KEY:-UNSET}"

if [[ "$quiet_mode" != "true" ]]; then
echo -e "${GREEN}✅ GitHub token environment configured${NC}"
fi
Expand Down
13 changes: 11 additions & 2 deletions scripts/runtime/setup-codex.sh
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ setup_codex() {
linux-x86_64)
codex_platform="x86_64-unknown-linux-gnu"
;;
linux-aarch64)
codex_platform="aarch64-unknown-linux-gnu"
;;
*)
log_error "Unsupported platform: $DETECTED_PLATFORM"
exit 1
Expand Down Expand Up @@ -88,18 +91,24 @@ setup_codex() {
local latest_release_url="https://api.github.com/repos/$CODEX_REPO/releases/latest"
local latest_tag

# DEBUG: Show token state right before API call
log_info "🔍 DEBUG: Token state before GitHub API call:"
log_info " GITHUB_TOKEN: ${GITHUB_TOKEN:+SET(${#GITHUB_TOKEN} chars)}${GITHUB_TOKEN:-UNSET}"
log_info " GITHUB_APM_PAT: ${GITHUB_APM_PAT:+SET(${#GITHUB_APM_PAT} chars)}${GITHUB_APM_PAT:-UNSET}"

# Try to get the latest release tag using curl
if command -v curl >/dev/null 2>&1; then
# Use authenticated request if GITHUB_TOKEN or GITHUB_APM_PAT is available
if [[ -n "${GITHUB_TOKEN:-}" ]]; then
log_info "Using authenticated GitHub API request (GITHUB_TOKEN)"
log_info "Using authenticated GitHub API request (GITHUB_TOKEN - ${#GITHUB_TOKEN} chars)"
local auth_header="Authorization: Bearer ${GITHUB_TOKEN}"
latest_tag=$(curl -s -H "$auth_header" "$latest_release_url" | grep '"tag_name":' | sed -E 's/.*"tag_name":[[:space:]]*"([^"]+)".*/\1/')
elif [[ -n "${GITHUB_APM_PAT:-}" ]]; then
log_info "Using authenticated GitHub API request (GITHUB_APM_PAT)"
log_info "Using authenticated GitHub API request (GITHUB_APM_PAT - ${#GITHUB_APM_PAT} chars)"
local auth_header="Authorization: Bearer ${GITHUB_APM_PAT}"
latest_tag=$(curl -s -H "$auth_header" "$latest_release_url" | grep '"tag_name":' | sed -E 's/.*"tag_name":[[:space:]]*"([^"]+)".*/\1/')
else
log_info "🚨 DEBUG: No tokens available - GITHUB_TOKEN and GITHUB_APM_PAT both unset!"
log_info "Using unauthenticated GitHub API request (60 requests/hour limit)"
latest_tag=$(curl -s "$latest_release_url" | grep '"tag_name":' | sed -E 's/.*"tag_name":[[:space:]]*"([^"]+)".*/\1/')
fi
Expand Down
3 changes: 3 additions & 0 deletions scripts/runtime/setup-common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ detect_platform() {
x86_64|amd64)
DETECTED_PLATFORM="linux-x86_64"
;;
aarch64|arm64)
DETECTED_PLATFORM="linux-aarch64"
;;
*)
log_error "Unsupported Linux architecture: $arch"
exit 1
Expand Down
3 changes: 3 additions & 0 deletions scripts/test-integration.sh
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ detect_platform() {
x86_64|amd64)
BINARY_NAME="apm-linux-x86_64"
;;
aarch64|arm64)
BINARY_NAME="apm-linux-arm64"
;;
*)
log_error "Unsupported Linux architecture: $arch"
exit 1
Expand Down
27 changes: 18 additions & 9 deletions src/apm_cli/core/token_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class GitHubTokenManager:
# Define token precedence for different use cases
TOKEN_PRECEDENCE = {
'copilot': ['GITHUB_COPILOT_PAT', 'GITHUB_TOKEN', 'GITHUB_APM_PAT'],
'models': ['GITHUB_TOKEN'], # GitHub Models requires user-scoped PAT
'models': ['GITHUB_TOKEN', 'GITHUB_APM_PAT'], # GitHub Models prefers user-scoped PAT, falls back to APM PAT
'modules': ['GITHUB_APM_PAT', 'GITHUB_TOKEN'], # APM module access
}

Expand Down Expand Up @@ -144,14 +144,23 @@ def _setup_copilot_tokens(self, env: Dict[str, str], available_tokens: Dict[str,
env[env_var] = copilot_token

def _setup_codex_tokens(self, env: Dict[str, str], available_tokens: Dict[str, str]):
"""Set up tokens for Codex CLI (preserve existing GITHUB_TOKEN)."""
# Codex uses GITHUB_TOKEN directly - only set if missing
if self.preserve_existing and 'GITHUB_TOKEN' in env:
return

models_token = self.get_token_for_purpose('models', available_tokens)
if models_token and 'GITHUB_TOKEN' not in env:
env['GITHUB_TOKEN'] = models_token
"""Set up tokens for Codex CLI (preserve existing tokens)."""
# Codex script checks for both GITHUB_TOKEN and GITHUB_APM_PAT
# Set up GITHUB_TOKEN if not present
if not (self.preserve_existing and 'GITHUB_TOKEN' in env):
models_token = self.get_token_for_purpose('models', available_tokens)
if models_token and 'GITHUB_TOKEN' not in env:
env['GITHUB_TOKEN'] = models_token
if models_token and 'GITHUB_TOKEN' not in env:
env['GITHUB_TOKEN'] = models_token

# Ensure GITHUB_APM_PAT is available if we have it
if not (self.preserve_existing and 'GITHUB_APM_PAT' in env):
apm_token = available_tokens.get('GITHUB_APM_PAT')
if apm_token and 'GITHUB_APM_PAT' not in env:
env['GITHUB_APM_PAT'] = apm_token
if apm_token and 'GITHUB_APM_PAT' not in env:
env['GITHUB_APM_PAT'] = apm_token

def _setup_llm_tokens(self, env: Dict[str, str], available_tokens: Dict[str, str]):
"""Set up tokens for LLM CLI."""
Expand Down
1 change: 1 addition & 0 deletions src/apm_cli/utils/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
'warning': '⚠️',
'error': '❌',
'check': '✅',
'cross': '❌',
'list': '📋',
'preview': '👀',
'robot': '🤖',
Expand Down
16 changes: 15 additions & 1 deletion tests/integration/test_runtime_smoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,28 @@ def run_command(cmd, check=True, capture_output=True, timeout=60, cwd=None):
if cwd is None:
cwd = Path(__file__).parent.parent.parent

# Ensure environment variables are properly passed to subprocess
env = os.environ.copy()

# DEBUG: Show GitHub-related environment variables being passed
print(f"🔍 DEBUG: Environment variables being passed to subprocess:")
for key in ['GITHUB_TOKEN', 'GITHUB_APM_PAT', 'GH_MODELS_PAT', 'GH_CLI_PAT', 'GH_PKG_PAT']:
value = env.get(key)
if value:
print(f" {key}: SET ({len(value)} chars)")
else:
print(f" {key}: UNSET")
print(f" Command: {cmd}")

result = subprocess.run(
cmd,
shell=True,
check=check,
capture_output=capture_output,
text=True,
timeout=timeout,
cwd=str(cwd)
cwd=str(cwd),
env=env # Explicitly pass environment
)
return result
except subprocess.TimeoutExpired:
Expand Down