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
21 changes: 15 additions & 6 deletions .github/workflows/example-consumer.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Example: how a repo would use the published action.
# Copy this to your repo as .github/workflows/cef-github-tracker.yaml
# and set repository secrets: WALLET_URI, NOTION_API_KEY.
# and set repository secrets: WALLET_URI, NOTION_API_KEY for legacy mode.
# Central sender mode does not require per-repo CEF wallet secrets once
# this action is released with central_sender_url defaulting to the
# CEF-owned sender endpoint.
#
# If the action lives in the same org (cef-ai/cef-github-tracker-action):
# uses: cef-ai/cef-github-tracker-action@v1
Expand All @@ -19,13 +22,19 @@ on:
jobs:
send:
runs-on: ubuntu-latest
env:
# These can come from organization-level secrets/variables granted
# to this repository.
WALLET_URI: ${{ secrets.WALLET_URI }}
NOTION_API_KEY: ${{ secrets.NOTION_API_KEY }}
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
CEF_DDC_BASE_URL: ${{ vars.CEF_DDC_BASE_URL }}
CEF_GAR_URL: ${{ vars.CEF_GAR_URL }}
CEF_AGENT_SERVICE: ${{ vars.CEF_AGENT_SERVICE }}
CEF_WORKSPACE: ${{ vars.CEF_WORKSPACE }}
CEF_STREAM: ${{ vars.CEF_STREAM }}
steps:
- uses: cef-ai/cef-github-tracker-action@v1
with:
wallet_uri: ${{ secrets.WALLET_URI }}
notion_api_key: ${{ secrets.NOTION_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
agent_service: '0x2bc3e8a0d6b12e660f519c74697f0929b9b815afc51544bdef08535a5d1c2d4f'
workspace: '2199'
stream: 'stream-fd9b5419'
wiki_check_branches: 'main,master'
89 changes: 50 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,73 +1,84 @@
# CEF GitHub Tracker Action

Reusable GitHub Action that sends PR, review, and push events to the [CEF Project Tazz](https://github.com/cef-ai/Project-Tazz-Execution-Log-Tracker) execution log tracker. One workflow file in any repo, no copy-paste of payload logic.
Reusable GitHub Action that sends PR, review, and push events to the CEF Vault GitHub agent.

This action is Vault-only. It reads the raw GitHub webhook payload from `GITHUB_EVENT_PATH`, adds a few CEF fields, and delegates to `cef-ai/Cef-Send-Event-Action`.

## Usage

Create `.github/workflows/cef-github-tracker.yaml` in your repo:
Create `.github/workflows/cef-github-tracker.yaml`:

```yaml
name: CEF GitHub Tracker

on:
pull_request:
types: [opened, closed, reopened]
types: [opened, closed, reopened, synchronize]
pull_request_review:
types: [submitted]
push:
branches: ['**']
branches: ["**"]

jobs:
send:
send-github-event:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
env:
CEF_AGENT_ID: ${{ vars.CEF_AGENT_ID }}
CEF_VAULT_WALLET_KEYSTORE_B64: ${{ secrets.CEF_VAULT_WALLET_KEYSTORE_B64 }}
CEF_VAULT_WALLET_KEYSTORE_PASSWORD: ${{ secrets.CEF_VAULT_WALLET_KEYSTORE_PASSWORD }}
GITHUB_TOKEN: ${{ github.token }}
steps:
- uses: cef-ai/cef-github-tracker-action@v1
with:
wallet_uri: ${{ secrets.WALLET_URI }}
notion_api_key: ${{ secrets.NOTION_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
agent_service: '0x2bc3e8a0d6b12e660f519c74697f0929b9b815afc51544bdef08535a5d1c2d4f'
workspace: '2199'
stream: 'stream-fd9b5419'
# Optional:
wiki_check_branches: 'main,master'
# ddc_base_url defaults to https://compute-1.devnet.ddc-dragon.com
```

## Required secrets
For the current test Vault, `Cef-Send-Event-Action` already defaults these values:

| Secret | Description |
|--------|-------------|
| `WALLET_URI` | CEF wallet URI for DDC authentication |
| `NOTION_API_KEY` | Notion internal integration token |
```text
CEF_VAULT_URL=https://vault-api.compute.test.ddcdragon.com
CEF_GAR_URL=https://gar.compute.test.ddcdragon.com
CEF_MARKETPLACE_URL=https://agent-marketplace.compute.test.ddcdragon.com
CEF_S3_GATEWAY_AUTH_INFO_URL=https://ddc-s3-gateway.compute.test.ddcdragon.com/auth/info
CEF_SCOPE=default
CEF_AGENT_ALIAS=productivity-agent
CEF_CUBBY_ALIAS=productivity_store
```

`GITHUB_TOKEN` is provided by GitHub Actions; pass it as `github_token` so the action can include it in the payload for the CEF agent.
Set them as repo/org variables only when the repo needs a different Vault environment or target.

## Inputs

| Input | Required | Default | Description |
|-------|----------|---------|-------------|
| `wallet_uri` | Yes | — | CEF wallet URI |
| `notion_api_key` | Yes | — | Notion API key |
| `github_token` | Yes | — | e.g. `${{ secrets.GITHUB_TOKEN }}` |
| `agent_service` | Yes | — | CEF agent service ID |
| `workspace` | Yes | — | CEF workspace ID |
| `stream` | Yes | — | CEF event stream ID |
| --- | --- | --- | --- |
| `notion_api_key` | No | `""` | Optional Notion token included in the payload |
| `github_token` | No | `""` | GitHub token for agent-side enrichment. Falls back to `GITHUB_TOKEN` or `CEF_GITHUB_TOKEN` env. |
| `gemini_api_key` | No | `""` | Optional Gemini API key included in the payload |
| `wiki_check_branches` | No | `main,master` | Branches that trigger wiki staleness checks |
| `ddc_base_url` | No | `https://compute-1.devnet.ddc-dragon.com` | DDC compute base URL |

## Pinning a version
## Payload

Use a tag (e.g. `@v1`, `@v1.0.1`) instead of `@main` so updates are intentional:
The payload sent to Vault is the raw GitHub webhook JSON plus:

```yaml
- uses: cef-ai/cef-github-tracker-action@v1
```json
{
"event_type": "GITHUB_ACTION_PR_EVENT",
"github_event_name": "pull_request",
"delivery_id": "github-run-id-run-attempt",
"notion_api_key": "...",
"github_token": "...",
"gemini_api_key": "...",
"wiki_check_branches": "main,master"
}
```

## Turning this into a repo
`Cef-Send-Event-Action` fills `repo`, `branch`, `pr_number`, and `head_sha` before publishing to Vault.

## Version Pinning

1. Create a new repo (e.g. `cef-ai/cef-github-tracker-action`).
2. Copy the contents of this folder (at least `action.yml` and this README) into the repo root.
3. Commit, push, and create a tag (e.g. `v1`) so others can use `@v1`.
4. In consuming repos, use `uses: cef-ai/cef-github-tracker-action@v1` (replace with your org/repo and tag).
# cef-github-tracker-action
Use a tag such as `@v1` after release:

```yaml
- uses: cef-ai/cef-github-tracker-action@v1
```
210 changes: 56 additions & 154 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,179 +1,81 @@
name: 'CEF GitHub Tracker'
description: 'Send GitHub events (PRs, reviews, pushes) to CEF execution log tracker (Project Tazz)'
name: "CEF GitHub Tracker"
description: "Send GitHub PR, review, and push events to the CEF Vault GitHub agent"

inputs:
wallet_uri:
required: true
description: 'CEF wallet URI for DDC authentication'
notion_api_key:
required: true
description: 'Notion internal integration token'
required: false
description: "Optional Notion token to include in the Vault payload"
default: ""
github_token:
required: true
description: 'GitHub token (e.g. secrets.GITHUB_TOKEN) for API access in the payload'
required: false
description: "GitHub token for agent-side GitHub API enrichment"
default: ""
gemini_api_key:
required: true
description: 'Google Gemini API key for AI operations'
agent_service:
required: true
description: 'CEF agent service ID'
workspace:
required: true
description: 'CEF workspace ID'
stream:
required: true
description: 'CEF event stream ID'
required: false
description: "Optional Gemini API key to include in the Vault payload"
default: ""
wiki_check_branches:
description: 'Comma-separated branches that trigger wiki staleness checks'
default: 'main,master'
ddc_base_url:
description: 'DDC compute base URL'
default: 'https://compute-1.devnet.ddc-dragon.com'
required: false
description: "Comma-separated branches that trigger wiki staleness checks"
default: "main,master"

runs:
using: 'composite'
using: "composite"
steps:
- id: payload
env:
NOTION_API_KEY: ${{ inputs.notion_api_key }}
GITHUB_TOKEN: ${{ inputs.github_token }}
GEMINI_API_KEY: ${{ inputs.gemini_api_key }}
WIKI_CHECK_BRANCHES: ${{ inputs.wiki_check_branches }}
INPUT_NOTION_API_KEY: ${{ inputs.notion_api_key }}
INPUT_GITHUB_TOKEN: ${{ inputs.github_token }}
INPUT_GEMINI_API_KEY: ${{ inputs.gemini_api_key }}
INPUT_WIKI_CHECK_BRANCHES: ${{ inputs.wiki_check_branches }}
shell: bash
run: |
set -e
set -euo pipefail

case "${{ github.event_name }}" in
pull_request)
jq -n \
--argjson e "$(cat $GITHUB_EVENT_PATH)" \
--arg notion "$NOTION_API_KEY" \
--arg token "$GITHUB_TOKEN" \
--arg gemini "$GEMINI_API_KEY" \
--arg wiki_branches "$WIKI_CHECK_BRANCHES" \
'{
event_type: "GITHUB_ACTION_PR_EVENT",
action: $e.action,
merged: ($e.pull_request.merged // false),
pr_number: $e.number,
pr_title: $e.pull_request.title,
pr_url: $e.pull_request.html_url,
pr_body: ($e.pull_request.body // ""),
repo: $e.repository.full_name,
author: $e.pull_request.user.login,
merged_by: ($e.pull_request.merged_by.login // null),
merged_at: ($e.pull_request.merged_at // null),
base_branch: ($e.pull_request.base.ref // null),
branch: ($e.pull_request.head.ref // null),
before: ($e.before // null),
after: ($e.after // null),
timestamp: ($e.pull_request.updated_at // $e.pull_request.created_at // ""),
notion_api_key: $notion,
github_token: $token,
gemini_api_key: $gemini,
wiki_check_branches: $wiki_branches
}' > payload.json
;;
pull_request_review)
jq -n \
--argjson e "$(cat $GITHUB_EVENT_PATH)" \
--arg notion "$NOTION_API_KEY" \
--arg token "$GITHUB_TOKEN" \
--arg gemini "$GEMINI_API_KEY" \
--arg wiki_branches "$WIKI_CHECK_BRANCHES" \
'{
event_type: "GITHUB_ACTION_PR_EVENT",
action: (
if $e.review.state == "approved" then "review_approved"
elif $e.review.state == "changes_requested" then "review_changes_requested"
else "review_commented"
end
),
merged: false,
pr_number: $e.pull_request.number,
pr_title: $e.pull_request.title,
pr_url: $e.pull_request.html_url,
pr_body: ($e.pull_request.body // ""),
repo: $e.repository.full_name,
author: $e.pull_request.user.login,
reviewer: $e.review.user.login,
merged_by: null,
merged_at: null,
base_branch: ($e.pull_request.base.ref // null),
branch: ($e.pull_request.head.ref // null),
before: null,
after: null,
timestamp: ($e.review.submitted_at // ""),
notion_api_key: $notion,
github_token: $token,
gemini_api_key: $gemini,
wiki_check_branches: $wiki_branches
}' > payload.json
;;
push)
jq -n \
--argjson e "$(cat $GITHUB_EVENT_PATH)" \
--arg notion "$NOTION_API_KEY" \
--arg token "$GITHUB_TOKEN" \
--arg gemini "$GEMINI_API_KEY" \
--arg wiki_branches "$WIKI_CHECK_BRANCHES" \
'
$e.ref as $ref |
($e.repository.default_branch // "main") as $default |
(if $ref == ("refs/heads/" + $default) then $default else ($ref | split("refs/heads/")[1]) end) as $branch |
($e.commits | length) as $n |
($e.commits[0].message // "") as $first_msg |
($e.after // "") as $after |
(if $n == 0 then true
elif ($ref == ("refs/heads/" + $default)) and ($n == 1) and ($first_msg | test("^Merge "; "i")) then true
else false end) as $skip_log |
{
event_type: "GITHUB_ACTION_PR_EVENT",
action: "branch_push",
merged: false,
is_branch_push: true,
branch: $branch,
head_sha: $after,
commit_messages: [$e.commits[].message],
repo: $e.repository.full_name,
author: ($e.pusher.login // $e.commits[0].author.username // "unknown"),
pr_number: 0,
pr_title: ("Branch: " + $branch),
pr_url: ("https://github.com/" + $e.repository.full_name + "/commit/" + $after),
pr_body: "",
merged_by: null,
merged_at: null,
base_branch: null,
before: $e.before,
after: $after,
timestamp: ($e.head_commit.timestamp // $e.repository.updated_at // ""),
notion_api_key: $notion,
github_token: $token,
gemini_api_key: $gemini,
skip_log: $skip_log,
wiki_check_branches: $wiki_branches
}
' > payload.json
pull_request|pull_request_review|push)
;;
*)
echo "Unsupported event: ${{ github.event_name }}"
echo "::error::Unsupported event: ${{ github.event_name }}"
exit 1
;;
esac
echo "payload<<EOF" >> $GITHUB_OUTPUT
cat payload.json >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

- uses: cef-ai/Cef-Send-Event-Action@main
notion_api_key="${INPUT_NOTION_API_KEY:-${CEF_NOTION_API_KEY:-${NOTION_API_KEY:-}}}"
github_token="${INPUT_GITHUB_TOKEN:-${GITHUB_TOKEN:-${CEF_GITHUB_TOKEN:-}}}"
gemini_api_key="${INPUT_GEMINI_API_KEY:-${CEF_GEMINI_API_KEY:-${GEMINI_API_KEY:-}}}"
wiki_check_branches="${INPUT_WIKI_CHECK_BRANCHES:-${CEF_GITHUB_TRACKER_WIKI_CHECK_BRANCHES:-main,master}}"
delivery_id="${GITHUB_RUN_ID:-local}-${GITHUB_RUN_ATTEMPT:-1}"

jq \
--arg event_type "GITHUB_ACTION_PR_EVENT" \
--arg github_event_name "${{ github.event_name }}" \
--arg notion "$notion_api_key" \
--arg token "$github_token" \
--arg gemini "$gemini_api_key" \
--arg wiki_branches "$wiki_check_branches" \
--arg delivery "$delivery_id" \
'. + {
event_type: $event_type,
github_event_name: $github_event_name,
notion_api_key: $notion,
github_token: $token,
gemini_api_key: $gemini,
wiki_check_branches: $wiki_branches,
delivery_id: (.delivery_id // $delivery)
}' "$GITHUB_EVENT_PATH" > payload.json

echo "payload<<EOF" >> "$GITHUB_OUTPUT"
cat payload.json >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"

- uses: cef-ai/Cef-Send-Event-Action@awei/central-sender-mode
with:
wallet_uri: ${{ inputs.wallet_uri }}
ddc_base_url: ${{ inputs.ddc_base_url }}
agent_service: ${{ inputs.agent_service }}
workspace: ${{ inputs.workspace }}
stream: ${{ inputs.stream }}
event_type: GITHUB_ACTION_PR_EVENT
event_payload: ${{ steps.payload.outputs.payload }}

# Keep the job (and therefore GITHUB_TOKEN) alive long enough for CEF
# to process the event. Without this, GITHUB_TOKEN is revoked when the
# job ends — often before CEF's fetch-code task pulls PR data.
# Keep the job (and therefore GITHUB_TOKEN) alive long enough for the
# agent to enrich the event before GitHub revokes the token.
- name: Keep GITHUB_TOKEN alive for CEF processing
shell: bash
run: sleep 30
Loading