diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml new file mode 100644 index 0000000..0eae641 --- /dev/null +++ b/.forgejo/workflows/ci.yml @@ -0,0 +1,84 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + branches: + - main + workflow_dispatch: + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + runs-on: grunt + steps: + - name: Checkout + uses: https://${{ secrets.READ_REPO_TOKEN }}@git.wxs.ro/xternal/checkout@v6.0.2 + with: + fetch-depth: 1 + + - name: Install Bun + run: | + if command -v bun &> /dev/null; then + echo "Bun already installed: $(bun --version)" + else + curl -fsSL https://bun.sh/install | bash + echo "$HOME/.bun/bin" >> "$GITHUB_PATH" + fi + + - name: Install dependencies + run: bun install + + - name: Run tests + run: bun test + + prettier: + runs-on: grunt + steps: + - name: Checkout + uses: https://${{ secrets.READ_REPO_TOKEN }}@git.wxs.ro/xternal/checkout@v6.0.2 + with: + fetch-depth: 1 + + - name: Install Bun + run: | + if command -v bun &> /dev/null; then + echo "Bun already installed: $(bun --version)" + else + curl -fsSL https://bun.sh/install | bash + echo "$HOME/.bun/bin" >> "$GITHUB_PATH" + fi + + - name: Install dependencies + run: bun install + + - name: Run prettier check + run: bun run format:check + + typecheck: + runs-on: grunt + steps: + - name: Checkout + uses: https://${{ secrets.READ_REPO_TOKEN }}@git.wxs.ro/xternal/checkout@v6.0.2 + with: + fetch-depth: 1 + + - name: Install Bun + run: | + if command -v bun &> /dev/null; then + echo "Bun already installed: $(bun --version)" + else + curl -fsSL https://bun.sh/install | bash + echo "$HOME/.bun/bin" >> "$GITHUB_PATH" + fi + + - name: Install dependencies + run: bun install + + - name: Run TypeScript type check + run: bun run typecheck diff --git a/.forgejo/workflows/test-action.yml b/.forgejo/workflows/test-action.yml new file mode 100644 index 0000000..cd444d5 --- /dev/null +++ b/.forgejo/workflows/test-action.yml @@ -0,0 +1,80 @@ +name: Test Action (Forgejo) + +on: + schedule: + # Weekly Monday at 06:00 UTC + - cron: "0 6 * * 1" + pull_request: + branches: + - main + paths: + - "src/**" + - "action.yml" + - ".forgejo/**" + - "base-action/**" + workflow_dispatch: + +concurrency: + group: test-action-${{ github.ref }} + cancel-in-progress: true + +jobs: + test-agent-mode: + name: Test Agent Mode on Forgejo + runs-on: grunt + steps: + - name: Checkout + uses: https://${{ secrets.READ_REPO_TOKEN }}@git.wxs.ro/xternal/checkout@v6.0.2 + with: + fetch-depth: 1 + + - name: Run Claude Code Action (agent mode) + id: claude + uses: ./ + with: + prompt: "Respond with exactly the text FORGEJO_PLATFORM_TEST_OK and nothing else. Do not use any tools." + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + github_token: ${{ secrets.FORGEJO_CLAUDE_TOKEN }} + platform: "forgejo" + env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + + - name: Verify execution output exists + run: | + EXEC_FILE="${{ steps.claude.outputs.execution_file }}" + if [ -z "$EXEC_FILE" ]; then + echo "FAIL: execution_file output is empty" + exit 1 + fi + if [ ! -f "$EXEC_FILE" ]; then + echo "FAIL: execution file does not exist at: $EXEC_FILE" + exit 1 + fi + echo "OK: execution file exists at: $EXEC_FILE" + + # Check that the output contains our test marker + if grep -q "FORGEJO_PLATFORM_TEST_OK" "$EXEC_FILE"; then + echo "OK: Output contains expected test marker" + else + echo "WARN: Test marker not found in output (Claude may have formatted differently)" + echo "--- Output contents (first 50 lines) ---" + head -50 "$EXEC_FILE" + fi + + - name: Debug on failure + if: failure() + run: | + echo "=== Debug Info ===" + echo "Platform env: PLATFORM=$PLATFORM FORGEJO=$FORGEJO" + echo "Server URL: $GITHUB_SERVER_URL" + echo "API URL: $GITHUB_API_URL" + echo "Event: ${{ github.event_name }}" + echo "Actor: ${{ github.actor }}" + echo "" + EXEC_FILE="${{ steps.claude.outputs.execution_file }}" + if [ -f "$EXEC_FILE" ]; then + echo "--- Execution file contents ---" + cat "$EXEC_FILE" + else + echo "No execution file found" + fi diff --git a/.forgejo/workflows/upstream-sync.yml b/.forgejo/workflows/upstream-sync.yml new file mode 100644 index 0000000..2015826 --- /dev/null +++ b/.forgejo/workflows/upstream-sync.yml @@ -0,0 +1,176 @@ +name: Upstream Sync Check + +on: + schedule: + # Weekly Monday at 08:00 UTC + - cron: "0 8 * * 1" + workflow_dispatch: + +jobs: + check-upstream: + name: Check for upstream updates + runs-on: grunt + steps: + - name: Checkout + uses: https://${{ secrets.READ_REPO_TOKEN }}@git.wxs.ro/xternal/checkout@v6.0.2 + with: + fetch-depth: 0 + + - name: Configure upstream remote + run: | + if ! git remote get-url upstream &> /dev/null; then + git remote add upstream https://github.com/anthropics/claude-code-action.git + fi + + - name: Fetch upstream + run: git fetch upstream main --quiet + + - name: Compare with upstream + id: compare + run: | + BEHIND_COUNT=$(git rev-list main..upstream/main --count) + AHEAD_COUNT=$(git rev-list upstream/main..main --count) + + echo "behind=$BEHIND_COUNT" >> "$GITHUB_OUTPUT" + echo "ahead=$AHEAD_COUNT" >> "$GITHUB_OUTPUT" + + echo "Our main is $BEHIND_COUNT commits behind and $AHEAD_COUNT commits ahead of upstream" + + if [ "$BEHIND_COUNT" -gt 0 ]; then + echo "needs_sync=true" >> "$GITHUB_OUTPUT" + + # Generate diff summary + echo "--- New upstream commits ---" + git log main..upstream/main --oneline | head -30 + + echo "" + echo "--- Files changed ---" + DIFF_STAT=$(git diff --stat main...upstream/main) + echo "$DIFF_STAT" + + # Save for issue body (escape newlines for multiline output) + { + echo "diff_stat<> "$GITHUB_OUTPUT" + + { + echo "commit_log<> "$GITHUB_OUTPUT" + else + echo "needs_sync=false" >> "$GITHUB_OUTPUT" + echo "Already up to date with upstream" + fi + + - name: Check for existing sync issue + if: steps.compare.outputs.needs_sync == 'true' + id: existing + run: | + # Search for open issues with the upstream-sync label + RESPONSE=$(curl -s \ + -H "Authorization: token ${{ github.token }}" \ + -H "Content-Type: application/json" \ + "${GITHUB_API_URL}/repos/${{ github.repository }}/issues?state=open&labels=upstream-sync&limit=1") + + ISSUE_COUNT=$(echo "$RESPONSE" | jq 'length') + + if [ "$ISSUE_COUNT" -gt 0 ]; then + ISSUE_NUMBER=$(echo "$RESPONSE" | jq '.[0].number') + echo "issue_exists=true" >> "$GITHUB_OUTPUT" + echo "issue_number=$ISSUE_NUMBER" >> "$GITHUB_OUTPUT" + echo "Found existing sync issue #$ISSUE_NUMBER" + else + echo "issue_exists=false" >> "$GITHUB_OUTPUT" + echo "No existing sync issue found" + fi + + - name: Create upstream-sync label + if: steps.compare.outputs.needs_sync == 'true' + run: | + # Create label if it doesn't exist (ignore 409 conflict) + curl -s -o /dev/null -w "%{http_code}" \ + -X POST \ + -H "Authorization: token ${{ github.token }}" \ + -H "Content-Type: application/json" \ + -d '{"name":"upstream-sync","color":"#0075ca","description":"Upstream sync tracking"}' \ + "${GITHUB_API_URL}/repos/${{ github.repository }}/labels" || true + + - name: Create or update sync issue + if: steps.compare.outputs.needs_sync == 'true' + run: | + BEHIND="${{ steps.compare.outputs.behind }}" + AHEAD="${{ steps.compare.outputs.ahead }}" + COMMIT_LOG=$(cat <<'LOG_EOF' + ${{ steps.compare.outputs.commit_log }} + LOG_EOF + ) + DIFF_STAT=$(cat <<'DIFF_EOF' + ${{ steps.compare.outputs.diff_stat }} + DIFF_EOF + ) + + BODY=$(cat <