From 522f06015f0c9ca8052dd0bf051a4de0cc5d3196 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sun, 17 May 2026 14:15:31 +0200 Subject: [PATCH 1/7] Add central sender mode --- .github/workflows/example-consumer.yaml | 5 +- README.md | 37 ++++- action.yml | 196 ++++++++++++++++++++++-- 3 files changed, 217 insertions(+), 21 deletions(-) diff --git a/.github/workflows/example-consumer.yaml b/.github/workflows/example-consumer.yaml index dcfdd85..67e56e3 100644 --- a/.github/workflows/example-consumer.yaml +++ b/.github/workflows/example-consumer.yaml @@ -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 diff --git a/README.md b/README.md index ed5ee3b..75c0980 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,13 @@ Reusable GitHub Action that sends PR, review, and push events to the [CEF Projec ## Usage +The action has two sender paths: + +- Central sender mode: this is the preferred path for deployed workflows. The action posts the GitHub event to one CEF-owned HTTPS endpoint, and that service owns the wallet, Vault endpoints, scope, agent connection, and other shared credentials. +- Legacy mode: the action calls `cef-ai/Cef-Send-Event-Action@main` with the wallet/workspace/stream inputs supplied by the calling workflow. + +With the default `sender_mode: auto`, central mode is used when `central_sender_url` has a value. Otherwise the action keeps using the legacy sender. To switch deployed workflows without editing their YAML, release this action with the `central_sender_url` input default set to the central sender endpoint. + Create `.github/workflows/cef-github-tracker.yaml` in your repo: ```yaml @@ -34,8 +41,22 @@ jobs: # ddc_base_url defaults to https://compute-1.devnet.ddc-dragon.com ``` +## Central sender rollout + +To move existing repositories without changing their workflow YAML: + +1. Deploy the CEF central sender service with the wallet keystore/passphrase, Vault/GAR/Marketplace URLs, scope, and agent alias configured as service-side secrets. +2. Set the `central_sender_url` default in `action.yml` to that HTTPS endpoint. +3. Release this action under the tag already used by deployed workflows, such as `v1`. + +The central sender receives the event payload plus GitHub run metadata. The action sends the caller's `github_token` only as the HTTP bearer token so the central service can validate the repository/run against GitHub before signing and publishing to CEF. The token is removed from the JSON payload sent to the central endpoint. + ## Required secrets +Central sender mode does not require every repository to define CEF wallet secrets. The wallet and CEF endpoint credentials belong in the central sender service. + +Legacy mode still needs these caller workflow secrets: + | Secret | Description | |--------|-------------| | `WALLET_URI` | CEF wallet URI for DDC authentication | @@ -47,14 +68,18 @@ jobs: | Input | Required | Default | Description | |-------|----------|---------|-------------| -| `wallet_uri` | Yes | — | CEF wallet URI | -| `notion_api_key` | Yes | — | Notion API key | +| `wallet_uri` | Legacy only | — | CEF wallet URI | +| `notion_api_key` | Legacy only | — | 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 | +| `gemini_api_key` | Legacy only | — | Google Gemini API key | +| `agent_service` | Legacy only | — | CEF agent service ID | +| `workspace` | Legacy only | — | CEF workspace ID | +| `stream` | Legacy only | — | CEF event stream ID | | `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 | +| `ddc_base_url` | Legacy only | `https://compute-1.devnet.ddc-dragon.com` | DDC compute base URL | +| `sender_mode` | No | `auto` | `auto`, `central`, or `legacy` | +| `central_sender_url` | No | — | HTTPS endpoint for the CEF central sender. Set the action default to enable central mode without changing caller workflows. | +| `central_sender_timeout_seconds` | No | `240` | Max wait for the central sender request | ## Pinning a version diff --git a/action.yml b/action.yml index 4b533a2..273f6f3 100644 --- a/action.yml +++ b/action.yml @@ -2,41 +2,98 @@ name: 'CEF GitHub Tracker' description: 'Send GitHub events (PRs, reviews, pushes) to CEF execution log tracker (Project Tazz)' inputs: wallet_uri: - required: true - description: 'CEF wallet URI for DDC authentication' + required: false + description: 'Legacy mode only: CEF wallet URI for DDC authentication' + default: '' notion_api_key: - required: true - description: 'Notion internal integration token' + required: false + description: 'Legacy mode only: Notion internal integration token' + default: '' github_token: required: true description: 'GitHub token (e.g. secrets.GITHUB_TOKEN) for API access in the payload' gemini_api_key: - required: true - description: 'Google Gemini API key for AI operations' + required: false + description: 'Legacy mode only: Google Gemini API key for AI operations' + default: '' agent_service: - required: true - description: 'CEF agent service ID' + required: false + description: 'Legacy mode only: CEF agent service ID' + default: '' workspace: - required: true - description: 'CEF workspace ID' + required: false + description: 'Legacy mode only: CEF workspace ID' + default: '' stream: - required: true - description: 'CEF event stream ID' + required: false + description: 'Legacy mode only: CEF event stream ID' + default: '' wiki_check_branches: description: 'Comma-separated branches that trigger wiki staleness checks' default: 'main,master' ddc_base_url: - description: 'DDC compute base URL' + description: 'Legacy mode only: DDC compute base URL' default: 'https://compute-1.devnet.ddc-dragon.com' + sender_mode: + required: false + description: 'auto uses the central sender when configured, otherwise legacy. Use central or legacy to force one path.' + default: 'auto' + central_sender_url: + required: false + description: 'Optional central CEF GitHub sender endpoint. Set this default in the action release to enable central mode without changing caller workflows.' + default: '' + central_sender_timeout_seconds: + required: false + description: 'Maximum time to wait for the central sender HTTP request.' + default: '240' runs: using: 'composite' steps: + - id: sender-config + env: + INPUT_SENDER_MODE: ${{ inputs.sender_mode }} + INPUT_CENTRAL_SENDER_URL: ${{ inputs.central_sender_url }} + shell: bash + run: | + set -euo pipefail + + mode="$(printf '%s' "${INPUT_SENDER_MODE:-auto}" | tr '[:upper:]' '[:lower:]')" + central_sender_url="${INPUT_CENTRAL_SENDER_URL:-}" + + case "$mode" in + auto) + if [ -n "$central_sender_url" ]; then + use_central=true + else + use_central=false + fi + ;; + central) + if [ -z "$central_sender_url" ]; then + echo "::error::sender_mode=central requires central_sender_url or a non-empty central_sender_url default in action.yml." + exit 1 + fi + use_central=true + ;; + legacy) + use_central=false + ;; + *) + echo "::error::Unsupported sender_mode '$INPUT_SENDER_MODE'. Use auto, central, or legacy." + exit 1 + ;; + esac + + echo "use_central=$use_central" >> "$GITHUB_OUTPUT" + echo "central_sender_url=$central_sender_url" >> "$GITHUB_OUTPUT" + - 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 }} + USE_CENTRAL_SENDER: ${{ steps.sender-config.outputs.use_central }} shell: bash run: | set -e @@ -157,11 +214,122 @@ runs: exit 1 ;; esac + + if [ "$USE_CENTRAL_SENDER" = "true" ]; then + jq 'del(.notion_api_key, .github_token, .gemini_api_key)' payload.json > payload-output.json + else + cp payload.json payload-output.json + fi + echo "payload<> $GITHUB_OUTPUT - cat payload.json >> $GITHUB_OUTPUT + cat payload-output.json >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT + - name: Send event via CEF central sender + if: ${{ steps.sender-config.outputs.use_central == 'true' }} + env: + CENTRAL_SENDER_URL: ${{ steps.sender-config.outputs.central_sender_url }} + CENTRAL_SENDER_TIMEOUT_SECONDS: ${{ inputs.central_sender_timeout_seconds }} + CEF_GITHUB_TOKEN: ${{ inputs.github_token }} + CEF_GITHUB_EVENT_NAME: ${{ github.event_name }} + CEF_GITHUB_REPOSITORY: ${{ github.repository }} + CEF_GITHUB_RUN_ID: ${{ github.run_id }} + CEF_GITHUB_RUN_ATTEMPT: ${{ github.run_attempt }} + CEF_GITHUB_WORKFLOW: ${{ github.workflow }} + CEF_GITHUB_JOB: ${{ github.job }} + CEF_GITHUB_REF: ${{ github.ref }} + CEF_GITHUB_SHA: ${{ github.sha }} + CEF_GITHUB_ACTOR: ${{ github.actor }} + CEF_GITHUB_SERVER_URL: ${{ github.server_url }} + CEF_GITHUB_API_URL: ${{ github.api_url }} + shell: bash + run: | + set -euo pipefail + + if [ -z "$CEF_GITHUB_TOKEN" ]; then + echo "::error::github_token is required for central sender mode." + exit 1 + fi + + case "$CENTRAL_SENDER_TIMEOUT_SECONDS" in + ''|*[!0-9]*) + echo "::error::central_sender_timeout_seconds must be an integer number of seconds." + exit 1 + ;; + esac + + jq 'del(.notion_api_key, .github_token, .gemini_api_key)' payload.json > central-event-payload.json + + jq -n \ + --arg source "cef-github-tracker-action" \ + --arg type "github_event" \ + --arg legacy_event_type "GITHUB_ACTION_PR_EVENT" \ + --arg event_name "$CEF_GITHUB_EVENT_NAME" \ + --arg repository "$CEF_GITHUB_REPOSITORY" \ + --arg run_id "$CEF_GITHUB_RUN_ID" \ + --arg run_attempt "$CEF_GITHUB_RUN_ATTEMPT" \ + --arg workflow "$CEF_GITHUB_WORKFLOW" \ + --arg job "$CEF_GITHUB_JOB" \ + --arg ref "$CEF_GITHUB_REF" \ + --arg sha "$CEF_GITHUB_SHA" \ + --arg actor "$CEF_GITHUB_ACTOR" \ + --arg server_url "$CEF_GITHUB_SERVER_URL" \ + --arg api_url "$CEF_GITHUB_API_URL" \ + --slurpfile payload central-event-payload.json \ + --slurpfile raw_event "$GITHUB_EVENT_PATH" \ + '{ + source: $source, + type: $type, + event_type: $type, + legacy_event_type: $legacy_event_type, + target: { + repository: $repository, + ref: $ref, + sha: $sha + }, + context: { + source: $source, + github: { + event_name: $event_name, + repository: $repository, + run_id: $run_id, + run_attempt: $run_attempt, + workflow: $workflow, + job: $job, + ref: $ref, + sha: $sha, + actor: $actor, + server_url: $server_url, + api_url: $api_url + } + }, + payload: $payload[0], + raw_event: $raw_event[0] + }' > central-sender-request.json + + response_file="$(mktemp)" + http_code="$(curl --silent --show-error --location \ + --output "$response_file" \ + --write-out '%{http_code}' \ + --max-time "$CENTRAL_SENDER_TIMEOUT_SECONDS" \ + --request POST "$CENTRAL_SENDER_URL" \ + --header "content-type: application/json" \ + --header "authorization: Bearer $CEF_GITHUB_TOKEN" \ + --header "x-github-event: $CEF_GITHUB_EVENT_NAME" \ + --header "x-github-repository: $CEF_GITHUB_REPOSITORY" \ + --header "x-github-run-id: $CEF_GITHUB_RUN_ID" \ + --data-binary @central-sender-request.json)" + + if [ "$http_code" -lt 200 ] || [ "$http_code" -gt 299 ]; then + echo "::error::CEF central sender returned HTTP $http_code." + cat "$response_file" + exit 1 + fi + + echo "CEF central sender accepted GitHub event (HTTP $http_code)." + - uses: cef-ai/Cef-Send-Event-Action@main + if: ${{ steps.sender-config.outputs.use_central != 'true' }} with: wallet_uri: ${{ inputs.wallet_uri }} ddc_base_url: ${{ inputs.ddc_base_url }} From de0779e36efe27aff2eb5f93b56abe6bece5717f Mon Sep 17 00:00:00 2001 From: Arthur Date: Sun, 17 May 2026 15:04:26 +0200 Subject: [PATCH 2/7] Support org-level env fallbacks --- .github/workflows/example-consumer.yaml | 16 +++++-- README.md | 42 +++++++++++++++++ action.yml | 63 +++++++++++++++---------- 3 files changed, 91 insertions(+), 30 deletions(-) diff --git a/.github/workflows/example-consumer.yaml b/.github/workflows/example-consumer.yaml index 67e56e3..23fed87 100644 --- a/.github/workflows/example-consumer.yaml +++ b/.github/workflows/example-consumer.yaml @@ -22,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' diff --git a/README.md b/README.md index 75c0980..7f7a3f6 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ The action has two sender paths: With the default `sender_mode: auto`, central mode is used when `central_sender_url` has a value. Otherwise the action keeps using the legacy sender. To switch deployed workflows without editing their YAML, release this action with the `central_sender_url` input default set to the central sender endpoint. +Inputs take precedence, but the action also reads inherited environment variables. That lets a consuming org define organization-level secrets/variables once, then map them into the job or workflow `env`. + Create `.github/workflows/cef-github-tracker.yaml` in your repo: ```yaml @@ -41,6 +43,33 @@ jobs: # ddc_base_url defaults to https://compute-1.devnet.ddc-dragon.com ``` +### Org-level values + +For a consuming org, define org-level secrets/variables and expose them to the job: + +GitHub configuration variables are available through the `vars` context, not automatically as shell environment variables, so the workflow maps them under `env`. + +```yaml +jobs: + send: + runs-on: ubuntu-latest + env: + 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: + github_token: ${{ secrets.GITHUB_TOKEN }} +``` + +The action also accepts `CEF_*` aliases for secrets: `CEF_WALLET_URI`, `CEF_NOTION_API_KEY`, `CEF_GEMINI_API_KEY`, and `CEF_GITHUB_TOKEN`. + ## Central sender rollout To move existing repositories without changing their workflow YAML: @@ -81,6 +110,19 @@ Legacy mode still needs these caller workflow secrets: | `central_sender_url` | No | — | HTTPS endpoint for the CEF central sender. Set the action default to enable central mode without changing caller workflows. | | `central_sender_timeout_seconds` | No | `240` | Max wait for the central sender request | +## Environment fallbacks + +| Env name | Purpose | +|----------|---------| +| `WALLET_URI` or `CEF_WALLET_URI` | Legacy SDK signer secret, consumed by `Cef-Send-Event-Action` | +| `NOTION_API_KEY` or `CEF_NOTION_API_KEY` | Notion token included in legacy payloads | +| `GEMINI_API_KEY` or `CEF_GEMINI_API_KEY` | Gemini token included in legacy payloads | +| `GITHUB_TOKEN` or `CEF_GITHUB_TOKEN` | GitHub token if not passed as `github_token` | +| `CEF_GITHUB_TRACKER_WIKI_CHECK_BRANCHES` | Default wiki-check branches | +| `CEF_GITHUB_TRACKER_SENDER_MODE` | `auto`, `central`, or `legacy` | +| `CEF_GITHUB_TRACKER_CENTRAL_SENDER_URL` | Central sender endpoint | +| `CEF_GITHUB_TRACKER_CENTRAL_SENDER_TIMEOUT_SECONDS` | Central sender timeout | + ## Pinning a version Use a tag (e.g. `@v1`, `@v1.0.1`) instead of `@main` so updates are intentional: diff --git a/action.yml b/action.yml index 273f6f3..164971a 100644 --- a/action.yml +++ b/action.yml @@ -30,7 +30,7 @@ inputs: default: '' wiki_check_branches: description: 'Comma-separated branches that trigger wiki staleness checks' - default: 'main,master' + default: '' ddc_base_url: description: 'Legacy mode only: DDC compute base URL' default: 'https://compute-1.devnet.ddc-dragon.com' @@ -45,7 +45,7 @@ inputs: central_sender_timeout_seconds: required: false description: 'Maximum time to wait for the central sender HTTP request.' - default: '240' + default: '' runs: using: 'composite' steps: @@ -57,8 +57,12 @@ runs: run: | set -euo pipefail - mode="$(printf '%s' "${INPUT_SENDER_MODE:-auto}" | tr '[:upper:]' '[:lower:]')" + mode="${INPUT_SENDER_MODE:-${CEF_GITHUB_TRACKER_SENDER_MODE:-${CEF_SENDER_MODE:-auto}}}" + mode="$(printf '%s' "$mode" | tr '[:upper:]' '[:lower:]')" central_sender_url="${INPUT_CENTRAL_SENDER_URL:-}" + if [ -z "$central_sender_url" ]; then + central_sender_url="${CEF_GITHUB_TRACKER_CENTRAL_SENDER_URL:-${CEF_CENTRAL_SENDER_URL:-}}" + fi case "$mode" in auto) @@ -89,22 +93,27 @@ runs: - 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 }} USE_CENTRAL_SENDER: ${{ steps.sender-config.outputs.use_central }} shell: bash run: | set -e + 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}}" + 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" \ + --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, @@ -131,10 +140,10 @@ runs: 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" \ + --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: ( @@ -167,10 +176,10 @@ runs: 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" \ + --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 | @@ -229,8 +238,8 @@ runs: if: ${{ steps.sender-config.outputs.use_central == 'true' }} env: CENTRAL_SENDER_URL: ${{ steps.sender-config.outputs.central_sender_url }} - CENTRAL_SENDER_TIMEOUT_SECONDS: ${{ inputs.central_sender_timeout_seconds }} - CEF_GITHUB_TOKEN: ${{ inputs.github_token }} + INPUT_CENTRAL_SENDER_TIMEOUT_SECONDS: ${{ inputs.central_sender_timeout_seconds }} + INPUT_GITHUB_TOKEN: ${{ inputs.github_token }} CEF_GITHUB_EVENT_NAME: ${{ github.event_name }} CEF_GITHUB_REPOSITORY: ${{ github.repository }} CEF_GITHUB_RUN_ID: ${{ github.run_id }} @@ -246,12 +255,15 @@ runs: run: | set -euo pipefail - if [ -z "$CEF_GITHUB_TOKEN" ]; then + github_token="${INPUT_GITHUB_TOKEN:-${GITHUB_TOKEN:-${CEF_GITHUB_TOKEN:-}}}" + central_sender_timeout_seconds="${INPUT_CENTRAL_SENDER_TIMEOUT_SECONDS:-${CEF_GITHUB_TRACKER_CENTRAL_SENDER_TIMEOUT_SECONDS:-${CEF_CENTRAL_SENDER_TIMEOUT_SECONDS:-240}}}" + + if [ -z "$github_token" ]; then echo "::error::github_token is required for central sender mode." exit 1 fi - case "$CENTRAL_SENDER_TIMEOUT_SECONDS" in + case "$central_sender_timeout_seconds" in ''|*[!0-9]*) echo "::error::central_sender_timeout_seconds must be an integer number of seconds." exit 1 @@ -311,10 +323,10 @@ runs: http_code="$(curl --silent --show-error --location \ --output "$response_file" \ --write-out '%{http_code}' \ - --max-time "$CENTRAL_SENDER_TIMEOUT_SECONDS" \ + --max-time "$central_sender_timeout_seconds" \ --request POST "$CENTRAL_SENDER_URL" \ --header "content-type: application/json" \ - --header "authorization: Bearer $CEF_GITHUB_TOKEN" \ + --header "authorization: Bearer $github_token" \ --header "x-github-event: $CEF_GITHUB_EVENT_NAME" \ --header "x-github-repository: $CEF_GITHUB_REPOSITORY" \ --header "x-github-run-id: $CEF_GITHUB_RUN_ID" \ @@ -338,6 +350,7 @@ runs: stream: ${{ inputs.stream }} event_type: GITHUB_ACTION_PR_EVENT event_payload: ${{ steps.payload.outputs.payload }} + sender_mode: legacy # Keep the job (and therefore GITHUB_TOKEN) alive long enough for CEF # to process the event. Without this, GITHUB_TOKEN is revoked when the From 20b49c5b334df7cc2504704584a8cd519cf012a8 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sun, 17 May 2026 15:11:28 +0200 Subject: [PATCH 3/7] Allow tracker org env token fallback --- README.md | 6 +++--- action.yml | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 7f7a3f6..73ffe14 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ jobs: stream: 'stream-fd9b5419' # Optional: wiki_check_branches: 'main,master' - # ddc_base_url defaults to https://compute-1.devnet.ddc-dragon.com + # ddc_base_url can also come from CEF_DDC_BASE_URL ``` ### Org-level values @@ -99,13 +99,13 @@ Legacy mode still needs these caller workflow secrets: |-------|----------|---------|-------------| | `wallet_uri` | Legacy only | — | CEF wallet URI | | `notion_api_key` | Legacy only | — | Notion API key | -| `github_token` | Yes | — | e.g. `${{ secrets.GITHUB_TOKEN }}` | +| `github_token` | No | — | e.g. `${{ secrets.GITHUB_TOKEN }}`. Falls back to `GITHUB_TOKEN` or `CEF_GITHUB_TOKEN` env. | | `gemini_api_key` | Legacy only | — | Google Gemini API key | | `agent_service` | Legacy only | — | CEF agent service ID | | `workspace` | Legacy only | — | CEF workspace ID | | `stream` | Legacy only | — | CEF event stream ID | | `wiki_check_branches` | No | `main,master` | Branches that trigger wiki staleness checks | -| `ddc_base_url` | Legacy only | `https://compute-1.devnet.ddc-dragon.com` | DDC compute base URL | +| `ddc_base_url` | Legacy only | — | DDC compute base URL | | `sender_mode` | No | `auto` | `auto`, `central`, or `legacy` | | `central_sender_url` | No | — | HTTPS endpoint for the CEF central sender. Set the action default to enable central mode without changing caller workflows. | | `central_sender_timeout_seconds` | No | `240` | Max wait for the central sender request | diff --git a/action.yml b/action.yml index 164971a..f9c809b 100644 --- a/action.yml +++ b/action.yml @@ -10,8 +10,9 @@ inputs: description: 'Legacy mode only: Notion internal integration token' default: '' github_token: - required: true + required: false description: 'GitHub token (e.g. secrets.GITHUB_TOKEN) for API access in the payload' + default: '' gemini_api_key: required: false description: 'Legacy mode only: Google Gemini API key for AI operations' @@ -33,7 +34,7 @@ inputs: default: '' ddc_base_url: description: 'Legacy mode only: DDC compute base URL' - default: 'https://compute-1.devnet.ddc-dragon.com' + default: '' sender_mode: required: false description: 'auto uses the central sender when configured, otherwise legacy. Use central or legacy to force one path.' From 1bb724bd42049982522f21129f77c8bbf740d006 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sun, 17 May 2026 17:08:38 +0200 Subject: [PATCH 4/7] Delegate Vault sender mode --- README.md | 35 ++++++++++++++++++++++++++++++----- action.yml | 15 ++++++++++++--- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 73ffe14..d340c75 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,13 @@ Reusable GitHub Action that sends PR, review, and push events to the [CEF Projec ## Usage -The action has two sender paths: +The action has three sender paths: -- Central sender mode: this is the preferred path for deployed workflows. The action posts the GitHub event to one CEF-owned HTTPS endpoint, and that service owns the wallet, Vault endpoints, scope, agent connection, and other shared credentials. +- Vault mode: the action delegates to `Cef-Send-Event-Action`, which publishes `github_event` directly to a Vault AgentConnection with `@cef-ai/vault-sdk`. +- Central sender mode: the action posts the GitHub event to one CEF-owned HTTPS endpoint, and that service owns the wallet, Vault endpoints, scope, agent connection, and other shared credentials. - Legacy mode: the action calls `cef-ai/Cef-Send-Event-Action@main` with the wallet/workspace/stream inputs supplied by the calling workflow. -With the default `sender_mode: auto`, central mode is used when `central_sender_url` has a value. Otherwise the action keeps using the legacy sender. To switch deployed workflows without editing their YAML, release this action with the `central_sender_url` input default set to the central sender endpoint. +With the default `sender_mode: auto`, central mode is used when `central_sender_url` has a value. Otherwise the delegated send action can use Vault mode when Vault env is configured, or legacy mode as a fallback. Inputs take precedence, but the action also reads inherited environment variables. That lets a consuming org define organization-level secrets/variables once, then map them into the job or workflow `env`. @@ -70,6 +71,21 @@ jobs: The action also accepts `CEF_*` aliases for secrets: `CEF_WALLET_URI`, `CEF_NOTION_API_KEY`, `CEF_GEMINI_API_KEY`, and `CEF_GITHUB_TOKEN`. +For Vault AgentConnection publishing, map these org-level values: + +```yaml +env: + CEF_GITHUB_TRACKER_SENDER_MODE: vault + CEF_VAULT_URL: ${{ vars.CEF_VAULT_URL }} + CEF_GAR_URL: ${{ vars.CEF_GAR_URL }} + CEF_MARKETPLACE_URL: ${{ vars.CEF_MARKETPLACE_URL }} + CEF_S3_GATEWAY_AUTH_INFO_URL: ${{ vars.CEF_S3_GATEWAY_AUTH_INFO_URL }} + CEF_VAULT_SCOPE: ${{ vars.CEF_VAULT_SCOPE }} + CEF_VAULT_AGENT_ID: ${{ vars.CEF_VAULT_AGENT_ID }} + CEF_VAULT_WALLET_KEYSTORE_B64: ${{ secrets.CEF_VAULT_WALLET_KEYSTORE_B64 }} + CEF_VAULT_WALLET_KEYSTORE_PASSWORD: ${{ secrets.CEF_VAULT_WALLET_KEYSTORE_PASSWORD }} +``` + ## Central sender rollout To move existing repositories without changing their workflow YAML: @@ -106,7 +122,7 @@ Legacy mode still needs these caller workflow secrets: | `stream` | Legacy only | — | CEF event stream ID | | `wiki_check_branches` | No | `main,master` | Branches that trigger wiki staleness checks | | `ddc_base_url` | Legacy only | — | DDC compute base URL | -| `sender_mode` | No | `auto` | `auto`, `central`, or `legacy` | +| `sender_mode` | No | `auto` | `auto`, `central`, `vault`, or `legacy` | | `central_sender_url` | No | — | HTTPS endpoint for the CEF central sender. Set the action default to enable central mode without changing caller workflows. | | `central_sender_timeout_seconds` | No | `240` | Max wait for the central sender request | @@ -119,9 +135,18 @@ Legacy mode still needs these caller workflow secrets: | `GEMINI_API_KEY` or `CEF_GEMINI_API_KEY` | Gemini token included in legacy payloads | | `GITHUB_TOKEN` or `CEF_GITHUB_TOKEN` | GitHub token if not passed as `github_token` | | `CEF_GITHUB_TRACKER_WIKI_CHECK_BRANCHES` | Default wiki-check branches | -| `CEF_GITHUB_TRACKER_SENDER_MODE` | `auto`, `central`, or `legacy` | +| `CEF_GITHUB_TRACKER_SENDER_MODE` | `auto`, `central`, `vault`, or `legacy` | | `CEF_GITHUB_TRACKER_CENTRAL_SENDER_URL` | Central sender endpoint | | `CEF_GITHUB_TRACKER_CENTRAL_SENDER_TIMEOUT_SECONDS` | Central sender timeout | +| `CEF_VAULT_URL` | Vault API URL, consumed by delegated send action | +| `CEF_MARKETPLACE_URL` | Agent Marketplace URL, consumed by delegated send action | +| `CEF_S3_GATEWAY_AUTH_INFO_URL` | S3 Gateway auth/info URL, consumed by delegated send action | +| `CEF_SCOPE` or `CEF_VAULT_SCOPE` | Vault scope | +| `CEF_AGENT_ID` or `CEF_VAULT_AGENT_ID` | Full AgentConnection target id | +| `CEF_AGENT_ALIAS` or `CEF_VAULT_AGENT_ALIAS` | Agent alias when target id is omitted | +| `CEF_CUBBY_ALIAS` or `CEF_VAULT_CUBBY_ALIAS` | Cubby alias when target id is omitted | +| `CEF_VAULT_WALLET_KEYSTORE_B64` | Base64-encoded Vault wallet keystore JSON | +| `CEF_VAULT_WALLET_KEYSTORE_PASSWORD` | Vault wallet keystore password | ## Pinning a version diff --git a/action.yml b/action.yml index f9c809b..d91b800 100644 --- a/action.yml +++ b/action.yml @@ -37,7 +37,7 @@ inputs: default: '' sender_mode: required: false - description: 'auto uses the central sender when configured, otherwise legacy. Use central or legacy to force one path.' + description: 'auto uses central or Vault when configured, otherwise legacy. Use central, vault, or legacy to force one path.' default: 'auto' central_sender_url: required: false @@ -69,8 +69,10 @@ runs: auto) if [ -n "$central_sender_url" ]; then use_central=true + send_action_mode=central else use_central=false + send_action_mode=auto fi ;; central) @@ -79,18 +81,25 @@ runs: exit 1 fi use_central=true + send_action_mode=central + ;; + vault) + use_central=false + send_action_mode=vault ;; legacy) use_central=false + send_action_mode=legacy ;; *) - echo "::error::Unsupported sender_mode '$INPUT_SENDER_MODE'. Use auto, central, or legacy." + echo "::error::Unsupported sender_mode '$INPUT_SENDER_MODE'. Use auto, central, vault, or legacy." exit 1 ;; esac echo "use_central=$use_central" >> "$GITHUB_OUTPUT" echo "central_sender_url=$central_sender_url" >> "$GITHUB_OUTPUT" + echo "send_action_mode=$send_action_mode" >> "$GITHUB_OUTPUT" - id: payload env: @@ -351,7 +360,7 @@ runs: stream: ${{ inputs.stream }} event_type: GITHUB_ACTION_PR_EVENT event_payload: ${{ steps.payload.outputs.payload }} - sender_mode: legacy + sender_mode: ${{ steps.sender-config.outputs.send_action_mode }} # Keep the job (and therefore GITHUB_TOKEN) alive long enough for CEF # to process the event. Without this, GITHUB_TOKEN is revoked when the From bd9aebc747d045765fa71e0ece74ae38a1b989c0 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sun, 17 May 2026 17:17:52 +0200 Subject: [PATCH 5/7] Send raw GitHub payloads in Vault mode --- README.md | 4 ++-- action.yml | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d340c75..889e301 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,11 @@ Reusable GitHub Action that sends PR, review, and push events to the [CEF Projec The action has three sender paths: -- Vault mode: the action delegates to `Cef-Send-Event-Action`, which publishes `github_event` directly to a Vault AgentConnection with `@cef-ai/vault-sdk`. +- Vault mode: the action delegates to `Cef-Send-Event-Action`, which publishes `github_event` directly to a Vault AgentConnection with `@cef-ai/vault-sdk`. In this mode the payload is the raw GitHub event JSON from `GITHUB_EVENT_PATH`, with CEF metadata/secrets added at the top level. - Central sender mode: the action posts the GitHub event to one CEF-owned HTTPS endpoint, and that service owns the wallet, Vault endpoints, scope, agent connection, and other shared credentials. - Legacy mode: the action calls `cef-ai/Cef-Send-Event-Action@main` with the wallet/workspace/stream inputs supplied by the calling workflow. -With the default `sender_mode: auto`, central mode is used when `central_sender_url` has a value. Otherwise the delegated send action can use Vault mode when Vault env is configured, or legacy mode as a fallback. +With the default `sender_mode: auto`, central mode is used when `central_sender_url` has a value. Otherwise the delegated send action can use Vault mode when Vault env is configured, or legacy mode as a fallback. When Vault env is detected, the delegated payload is the same raw GitHub event body that the runner receives. Inputs take precedence, but the action also reads inherited environment variables. That lets a consuming org define organization-level secrets/variables once, then map them into the job or workflow `env`. diff --git a/action.yml b/action.yml index d91b800..46ae9ee 100644 --- a/action.yml +++ b/action.yml @@ -65,14 +65,39 @@ runs: central_sender_url="${CEF_GITHUB_TRACKER_CENTRAL_SENDER_URL:-${CEF_CENTRAL_SENDER_URL:-}}" fi + has_vault_wallet=false + if [ -n "${CEF_VAULT_WALLET_KEYSTORE_B64:-}" ] || + [ -n "${CEF_VAULT_WALLET_KEYSTORE_JSON:-}" ] || + [ -n "${CEF_VAULT_WALLET_MNEMONIC:-}" ] || + [ -n "${CEF_VAULT_WALLET_SEED_HEX:-}" ]; then + has_vault_wallet=true + elif [ -n "${WALLET_KEYSTORE_PATH:-}" ] && + [ -n "${WALLET_KEYSTORE_PASSWORD:-${CEF_VAULT_WALLET_KEYSTORE_PASSWORD:-}}" ]; then + has_vault_wallet=true + fi + + has_vault_config=false + if [ -n "${CEF_VAULT_URL:-${VAULT_URL:-}}" ] || + [ -n "${CEF_AGENT_ID:-${CEF_VAULT_AGENT_ID:-${AGENT_ID:-}}}" ] || + [ -n "${CEF_AGENT_ALIAS:-${CEF_VAULT_AGENT_ALIAS:-${AGENT_ALIAS:-}}}" ] || + [ -n "${CEF_CUBBY_ALIAS:-${CEF_VAULT_CUBBY_ALIAS:-${CUBBY_ALIAS:-}}}" ]; then + has_vault_config=true + fi + case "$mode" in auto) if [ -n "$central_sender_url" ]; then use_central=true send_action_mode=central + use_raw_github_event=false else use_central=false send_action_mode=auto + if [ "$has_vault_wallet" = "true" ] && [ "$has_vault_config" = "true" ]; then + use_raw_github_event=true + else + use_raw_github_event=false + fi fi ;; central) @@ -82,14 +107,17 @@ runs: fi use_central=true send_action_mode=central + use_raw_github_event=false ;; vault) use_central=false send_action_mode=vault + use_raw_github_event=true ;; legacy) use_central=false send_action_mode=legacy + use_raw_github_event=false ;; *) echo "::error::Unsupported sender_mode '$INPUT_SENDER_MODE'. Use auto, central, vault, or legacy." @@ -100,6 +128,7 @@ runs: echo "use_central=$use_central" >> "$GITHUB_OUTPUT" echo "central_sender_url=$central_sender_url" >> "$GITHUB_OUTPUT" echo "send_action_mode=$send_action_mode" >> "$GITHUB_OUTPUT" + echo "use_raw_github_event=$use_raw_github_event" >> "$GITHUB_OUTPUT" - id: payload env: @@ -108,6 +137,7 @@ runs: INPUT_GEMINI_API_KEY: ${{ inputs.gemini_api_key }} INPUT_WIKI_CHECK_BRANCHES: ${{ inputs.wiki_check_branches }} USE_CENTRAL_SENDER: ${{ steps.sender-config.outputs.use_central }} + USE_RAW_GITHUB_EVENT: ${{ steps.sender-config.outputs.use_raw_github_event }} shell: bash run: | set -e @@ -116,6 +146,32 @@ runs: 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}}" + if [ "$USE_RAW_GITHUB_EVENT" = "true" ]; then + case "${{ github.event_name }}" in + pull_request|pull_request_review|push) + delivery_id="${GITHUB_RUN_ID:-local}-${GITHUB_RUN_ATTEMPT:-1}" + jq \ + --arg event_type "GITHUB_ACTION_PR_EVENT" \ + --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, + 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 "Unsupported event: ${{ github.event_name }}" + exit 1 + ;; + esac + else case "${{ github.event_name }}" in pull_request) jq -n \ @@ -233,6 +289,7 @@ runs: exit 1 ;; esac + fi if [ "$USE_CENTRAL_SENDER" = "true" ]; then jq 'del(.notion_api_key, .github_token, .gemini_api_key)' payload.json > payload-output.json From 158f99544100008ca52124d3ffe895ab605c4642 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sun, 17 May 2026 20:51:36 +0200 Subject: [PATCH 6/7] Use send action feature branch for Vault tests --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 46ae9ee..80513e9 100644 --- a/action.yml +++ b/action.yml @@ -407,7 +407,7 @@ runs: echo "CEF central sender accepted GitHub event (HTTP $http_code)." - - uses: cef-ai/Cef-Send-Event-Action@main + - uses: cef-ai/Cef-Send-Event-Action@awei/central-sender-mode if: ${{ steps.sender-config.outputs.use_central != 'true' }} with: wallet_uri: ${{ inputs.wallet_uri }} From 6864085d18367f8db93cf5d56e55756ce6ef81b7 Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 21 May 2026 11:48:10 +0200 Subject: [PATCH 7/7] Simplify tracker to Vault only --- README.md | 175 ++++++--------------- action.yml | 434 ++++++----------------------------------------------- 2 files changed, 91 insertions(+), 518 deletions(-) diff --git a/README.md b/README.md index 889e301..7a2e53c 100644 --- a/README.md +++ b/README.md @@ -1,165 +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. -## Usage - -The action has three sender paths: - -- Vault mode: the action delegates to `Cef-Send-Event-Action`, which publishes `github_event` directly to a Vault AgentConnection with `@cef-ai/vault-sdk`. In this mode the payload is the raw GitHub event JSON from `GITHUB_EVENT_PATH`, with CEF metadata/secrets added at the top level. -- Central sender mode: the action posts the GitHub event to one CEF-owned HTTPS endpoint, and that service owns the wallet, Vault endpoints, scope, agent connection, and other shared credentials. -- Legacy mode: the action calls `cef-ai/Cef-Send-Event-Action@main` with the wallet/workspace/stream inputs supplied by the calling workflow. - -With the default `sender_mode: auto`, central mode is used when `central_sender_url` has a value. Otherwise the delegated send action can use Vault mode when Vault env is configured, or legacy mode as a fallback. When Vault env is detected, the delegated payload is the same raw GitHub event body that the runner receives. +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`. -Inputs take precedence, but the action also reads inherited environment variables. That lets a consuming org define organization-level secrets/variables once, then map them into the job or workflow `env`. +## 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: ['**'] - -jobs: - send: - runs-on: ubuntu-latest - 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 can also come from CEF_DDC_BASE_URL -``` - -### Org-level values - -For a consuming org, define org-level secrets/variables and expose them to the job: - -GitHub configuration variables are available through the `vars` context, not automatically as shell environment variables, so the workflow maps them under `env`. + branches: ["**"] -```yaml jobs: - send: + send-github-event: runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read env: - 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 }} + 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: - github_token: ${{ secrets.GITHUB_TOKEN }} ``` -The action also accepts `CEF_*` aliases for secrets: `CEF_WALLET_URI`, `CEF_NOTION_API_KEY`, `CEF_GEMINI_API_KEY`, and `CEF_GITHUB_TOKEN`. - -For Vault AgentConnection publishing, map these org-level values: +For the current test Vault, `Cef-Send-Event-Action` already defaults these values: -```yaml -env: - CEF_GITHUB_TRACKER_SENDER_MODE: vault - CEF_VAULT_URL: ${{ vars.CEF_VAULT_URL }} - CEF_GAR_URL: ${{ vars.CEF_GAR_URL }} - CEF_MARKETPLACE_URL: ${{ vars.CEF_MARKETPLACE_URL }} - CEF_S3_GATEWAY_AUTH_INFO_URL: ${{ vars.CEF_S3_GATEWAY_AUTH_INFO_URL }} - CEF_VAULT_SCOPE: ${{ vars.CEF_VAULT_SCOPE }} - CEF_VAULT_AGENT_ID: ${{ vars.CEF_VAULT_AGENT_ID }} - CEF_VAULT_WALLET_KEYSTORE_B64: ${{ secrets.CEF_VAULT_WALLET_KEYSTORE_B64 }} - CEF_VAULT_WALLET_KEYSTORE_PASSWORD: ${{ secrets.CEF_VAULT_WALLET_KEYSTORE_PASSWORD }} +```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 ``` -## Central sender rollout - -To move existing repositories without changing their workflow YAML: +Set them as repo/org variables only when the repo needs a different Vault environment or target. -1. Deploy the CEF central sender service with the wallet keystore/passphrase, Vault/GAR/Marketplace URLs, scope, and agent alias configured as service-side secrets. -2. Set the `central_sender_url` default in `action.yml` to that HTTPS endpoint. -3. Release this action under the tag already used by deployed workflows, such as `v1`. - -The central sender receives the event payload plus GitHub run metadata. The action sends the caller's `github_token` only as the HTTP bearer token so the central service can validate the repository/run against GitHub before signing and publishing to CEF. The token is removed from the JSON payload sent to the central endpoint. +## Inputs -## Required secrets +| Input | Required | Default | Description | +| --- | --- | --- | --- | +| `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 | -Central sender mode does not require every repository to define CEF wallet secrets. The wallet and CEF endpoint credentials belong in the central sender service. +## Payload -Legacy mode still needs these caller workflow secrets: +The payload sent to Vault is the raw GitHub webhook JSON plus: -| Secret | Description | -|--------|-------------| -| `WALLET_URI` | CEF wallet URI for DDC authentication | -| `NOTION_API_KEY` | Notion internal integration token | +```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" +} +``` -`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. +`Cef-Send-Event-Action` fills `repo`, `branch`, `pr_number`, and `head_sha` before publishing to Vault. -## Inputs +## Version Pinning -| Input | Required | Default | Description | -|-------|----------|---------|-------------| -| `wallet_uri` | Legacy only | — | CEF wallet URI | -| `notion_api_key` | Legacy only | — | Notion API key | -| `github_token` | No | — | e.g. `${{ secrets.GITHUB_TOKEN }}`. Falls back to `GITHUB_TOKEN` or `CEF_GITHUB_TOKEN` env. | -| `gemini_api_key` | Legacy only | — | Google Gemini API key | -| `agent_service` | Legacy only | — | CEF agent service ID | -| `workspace` | Legacy only | — | CEF workspace ID | -| `stream` | Legacy only | — | CEF event stream ID | -| `wiki_check_branches` | No | `main,master` | Branches that trigger wiki staleness checks | -| `ddc_base_url` | Legacy only | — | DDC compute base URL | -| `sender_mode` | No | `auto` | `auto`, `central`, `vault`, or `legacy` | -| `central_sender_url` | No | — | HTTPS endpoint for the CEF central sender. Set the action default to enable central mode without changing caller workflows. | -| `central_sender_timeout_seconds` | No | `240` | Max wait for the central sender request | - -## Environment fallbacks - -| Env name | Purpose | -|----------|---------| -| `WALLET_URI` or `CEF_WALLET_URI` | Legacy SDK signer secret, consumed by `Cef-Send-Event-Action` | -| `NOTION_API_KEY` or `CEF_NOTION_API_KEY` | Notion token included in legacy payloads | -| `GEMINI_API_KEY` or `CEF_GEMINI_API_KEY` | Gemini token included in legacy payloads | -| `GITHUB_TOKEN` or `CEF_GITHUB_TOKEN` | GitHub token if not passed as `github_token` | -| `CEF_GITHUB_TRACKER_WIKI_CHECK_BRANCHES` | Default wiki-check branches | -| `CEF_GITHUB_TRACKER_SENDER_MODE` | `auto`, `central`, `vault`, or `legacy` | -| `CEF_GITHUB_TRACKER_CENTRAL_SENDER_URL` | Central sender endpoint | -| `CEF_GITHUB_TRACKER_CENTRAL_SENDER_TIMEOUT_SECONDS` | Central sender timeout | -| `CEF_VAULT_URL` | Vault API URL, consumed by delegated send action | -| `CEF_MARKETPLACE_URL` | Agent Marketplace URL, consumed by delegated send action | -| `CEF_S3_GATEWAY_AUTH_INFO_URL` | S3 Gateway auth/info URL, consumed by delegated send action | -| `CEF_SCOPE` or `CEF_VAULT_SCOPE` | Vault scope | -| `CEF_AGENT_ID` or `CEF_VAULT_AGENT_ID` | Full AgentConnection target id | -| `CEF_AGENT_ALIAS` or `CEF_VAULT_AGENT_ALIAS` | Agent alias when target id is omitted | -| `CEF_CUBBY_ALIAS` or `CEF_VAULT_CUBBY_ALIAS` | Cubby alias when target id is omitted | -| `CEF_VAULT_WALLET_KEYSTORE_B64` | Base64-encoded Vault wallet keystore JSON | -| `CEF_VAULT_WALLET_KEYSTORE_PASSWORD` | Vault wallet keystore password | - -## Pinning a version - -Use a tag (e.g. `@v1`, `@v1.0.1`) instead of `@main` so updates are intentional: +Use a tag such as `@v1` after release: ```yaml - uses: cef-ai/cef-github-tracker-action@v1 ``` - -## Turning this into a repo - -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 diff --git a/action.yml b/action.yml index 80513e9..dad938b 100644 --- a/action.yml +++ b/action.yml @@ -1,427 +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: false - description: 'Legacy mode only: CEF wallet URI for DDC authentication' - default: '' notion_api_key: required: false - description: 'Legacy mode only: Notion internal integration token' - default: '' + description: "Optional Notion token to include in the Vault payload" + default: "" github_token: required: false - description: 'GitHub token (e.g. secrets.GITHUB_TOKEN) for API access in the payload' - default: '' + description: "GitHub token for agent-side GitHub API enrichment" + default: "" gemini_api_key: required: false - description: 'Legacy mode only: Google Gemini API key for AI operations' - default: '' - agent_service: - required: false - description: 'Legacy mode only: CEF agent service ID' - default: '' - workspace: - required: false - description: 'Legacy mode only: CEF workspace ID' - default: '' - stream: - required: false - description: 'Legacy mode only: CEF event stream ID' - default: '' + 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: '' - ddc_base_url: - description: 'Legacy mode only: DDC compute base URL' - default: '' - sender_mode: - required: false - description: 'auto uses central or Vault when configured, otherwise legacy. Use central, vault, or legacy to force one path.' - default: 'auto' - central_sender_url: - required: false - description: 'Optional central CEF GitHub sender endpoint. Set this default in the action release to enable central mode without changing caller workflows.' - default: '' - central_sender_timeout_seconds: required: false - description: 'Maximum time to wait for the central sender HTTP request.' - default: '' + description: "Comma-separated branches that trigger wiki staleness checks" + default: "main,master" + runs: - using: 'composite' + using: "composite" steps: - - id: sender-config - env: - INPUT_SENDER_MODE: ${{ inputs.sender_mode }} - INPUT_CENTRAL_SENDER_URL: ${{ inputs.central_sender_url }} - shell: bash - run: | - set -euo pipefail - - mode="${INPUT_SENDER_MODE:-${CEF_GITHUB_TRACKER_SENDER_MODE:-${CEF_SENDER_MODE:-auto}}}" - mode="$(printf '%s' "$mode" | tr '[:upper:]' '[:lower:]')" - central_sender_url="${INPUT_CENTRAL_SENDER_URL:-}" - if [ -z "$central_sender_url" ]; then - central_sender_url="${CEF_GITHUB_TRACKER_CENTRAL_SENDER_URL:-${CEF_CENTRAL_SENDER_URL:-}}" - fi - - has_vault_wallet=false - if [ -n "${CEF_VAULT_WALLET_KEYSTORE_B64:-}" ] || - [ -n "${CEF_VAULT_WALLET_KEYSTORE_JSON:-}" ] || - [ -n "${CEF_VAULT_WALLET_MNEMONIC:-}" ] || - [ -n "${CEF_VAULT_WALLET_SEED_HEX:-}" ]; then - has_vault_wallet=true - elif [ -n "${WALLET_KEYSTORE_PATH:-}" ] && - [ -n "${WALLET_KEYSTORE_PASSWORD:-${CEF_VAULT_WALLET_KEYSTORE_PASSWORD:-}}" ]; then - has_vault_wallet=true - fi - - has_vault_config=false - if [ -n "${CEF_VAULT_URL:-${VAULT_URL:-}}" ] || - [ -n "${CEF_AGENT_ID:-${CEF_VAULT_AGENT_ID:-${AGENT_ID:-}}}" ] || - [ -n "${CEF_AGENT_ALIAS:-${CEF_VAULT_AGENT_ALIAS:-${AGENT_ALIAS:-}}}" ] || - [ -n "${CEF_CUBBY_ALIAS:-${CEF_VAULT_CUBBY_ALIAS:-${CUBBY_ALIAS:-}}}" ]; then - has_vault_config=true - fi - - case "$mode" in - auto) - if [ -n "$central_sender_url" ]; then - use_central=true - send_action_mode=central - use_raw_github_event=false - else - use_central=false - send_action_mode=auto - if [ "$has_vault_wallet" = "true" ] && [ "$has_vault_config" = "true" ]; then - use_raw_github_event=true - else - use_raw_github_event=false - fi - fi - ;; - central) - if [ -z "$central_sender_url" ]; then - echo "::error::sender_mode=central requires central_sender_url or a non-empty central_sender_url default in action.yml." - exit 1 - fi - use_central=true - send_action_mode=central - use_raw_github_event=false - ;; - vault) - use_central=false - send_action_mode=vault - use_raw_github_event=true - ;; - legacy) - use_central=false - send_action_mode=legacy - use_raw_github_event=false - ;; - *) - echo "::error::Unsupported sender_mode '$INPUT_SENDER_MODE'. Use auto, central, vault, or legacy." - exit 1 - ;; - esac - - echo "use_central=$use_central" >> "$GITHUB_OUTPUT" - echo "central_sender_url=$central_sender_url" >> "$GITHUB_OUTPUT" - echo "send_action_mode=$send_action_mode" >> "$GITHUB_OUTPUT" - echo "use_raw_github_event=$use_raw_github_event" >> "$GITHUB_OUTPUT" - - id: payload env: 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 }} - USE_CENTRAL_SENDER: ${{ steps.sender-config.outputs.use_central }} - USE_RAW_GITHUB_EVENT: ${{ steps.sender-config.outputs.use_raw_github_event }} shell: bash run: | - set -e - 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}}" + set -euo pipefail - if [ "$USE_RAW_GITHUB_EVENT" = "true" ]; then - case "${{ github.event_name }}" in - pull_request|pull_request_review|push) - delivery_id="${GITHUB_RUN_ID:-local}-${GITHUB_RUN_ATTEMPT:-1}" - jq \ - --arg event_type "GITHUB_ACTION_PR_EVENT" \ - --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, - 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 "Unsupported event: ${{ github.event_name }}" - exit 1 - ;; - esac - else 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 - fi - - if [ "$USE_CENTRAL_SENDER" = "true" ]; then - jq 'del(.notion_api_key, .github_token, .gemini_api_key)' payload.json > payload-output.json - else - cp payload.json payload-output.json - fi - - echo "payload<> $GITHUB_OUTPUT - cat payload-output.json >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - - - name: Send event via CEF central sender - if: ${{ steps.sender-config.outputs.use_central == 'true' }} - env: - CENTRAL_SENDER_URL: ${{ steps.sender-config.outputs.central_sender_url }} - INPUT_CENTRAL_SENDER_TIMEOUT_SECONDS: ${{ inputs.central_sender_timeout_seconds }} - INPUT_GITHUB_TOKEN: ${{ inputs.github_token }} - CEF_GITHUB_EVENT_NAME: ${{ github.event_name }} - CEF_GITHUB_REPOSITORY: ${{ github.repository }} - CEF_GITHUB_RUN_ID: ${{ github.run_id }} - CEF_GITHUB_RUN_ATTEMPT: ${{ github.run_attempt }} - CEF_GITHUB_WORKFLOW: ${{ github.workflow }} - CEF_GITHUB_JOB: ${{ github.job }} - CEF_GITHUB_REF: ${{ github.ref }} - CEF_GITHUB_SHA: ${{ github.sha }} - CEF_GITHUB_ACTOR: ${{ github.actor }} - CEF_GITHUB_SERVER_URL: ${{ github.server_url }} - CEF_GITHUB_API_URL: ${{ github.api_url }} - shell: bash - run: | - set -euo pipefail + notion_api_key="${INPUT_NOTION_API_KEY:-${CEF_NOTION_API_KEY:-${NOTION_API_KEY:-}}}" github_token="${INPUT_GITHUB_TOKEN:-${GITHUB_TOKEN:-${CEF_GITHUB_TOKEN:-}}}" - central_sender_timeout_seconds="${INPUT_CENTRAL_SENDER_TIMEOUT_SECONDS:-${CEF_GITHUB_TRACKER_CENTRAL_SENDER_TIMEOUT_SECONDS:-${CEF_CENTRAL_SENDER_TIMEOUT_SECONDS:-240}}}" - - if [ -z "$github_token" ]; then - echo "::error::github_token is required for central sender mode." - exit 1 - fi - - case "$central_sender_timeout_seconds" in - ''|*[!0-9]*) - echo "::error::central_sender_timeout_seconds must be an integer number of seconds." - exit 1 - ;; - esac - - jq 'del(.notion_api_key, .github_token, .gemini_api_key)' payload.json > central-event-payload.json - - jq -n \ - --arg source "cef-github-tracker-action" \ - --arg type "github_event" \ - --arg legacy_event_type "GITHUB_ACTION_PR_EVENT" \ - --arg event_name "$CEF_GITHUB_EVENT_NAME" \ - --arg repository "$CEF_GITHUB_REPOSITORY" \ - --arg run_id "$CEF_GITHUB_RUN_ID" \ - --arg run_attempt "$CEF_GITHUB_RUN_ATTEMPT" \ - --arg workflow "$CEF_GITHUB_WORKFLOW" \ - --arg job "$CEF_GITHUB_JOB" \ - --arg ref "$CEF_GITHUB_REF" \ - --arg sha "$CEF_GITHUB_SHA" \ - --arg actor "$CEF_GITHUB_ACTOR" \ - --arg server_url "$CEF_GITHUB_SERVER_URL" \ - --arg api_url "$CEF_GITHUB_API_URL" \ - --slurpfile payload central-event-payload.json \ - --slurpfile raw_event "$GITHUB_EVENT_PATH" \ - '{ - source: $source, - type: $type, - event_type: $type, - legacy_event_type: $legacy_event_type, - target: { - repository: $repository, - ref: $ref, - sha: $sha - }, - context: { - source: $source, - github: { - event_name: $event_name, - repository: $repository, - run_id: $run_id, - run_attempt: $run_attempt, - workflow: $workflow, - job: $job, - ref: $ref, - sha: $sha, - actor: $actor, - server_url: $server_url, - api_url: $api_url - } - }, - payload: $payload[0], - raw_event: $raw_event[0] - }' > central-sender-request.json - - response_file="$(mktemp)" - http_code="$(curl --silent --show-error --location \ - --output "$response_file" \ - --write-out '%{http_code}' \ - --max-time "$central_sender_timeout_seconds" \ - --request POST "$CENTRAL_SENDER_URL" \ - --header "content-type: application/json" \ - --header "authorization: Bearer $github_token" \ - --header "x-github-event: $CEF_GITHUB_EVENT_NAME" \ - --header "x-github-repository: $CEF_GITHUB_REPOSITORY" \ - --header "x-github-run-id: $CEF_GITHUB_RUN_ID" \ - --data-binary @central-sender-request.json)" - - if [ "$http_code" -lt 200 ] || [ "$http_code" -gt 299 ]; then - echo "::error::CEF central sender returned HTTP $http_code." - cat "$response_file" - exit 1 - fi - - echo "CEF central sender accepted GitHub event (HTTP $http_code)." + 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<> "$GITHUB_OUTPUT" + cat payload.json >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" - uses: cef-ai/Cef-Send-Event-Action@awei/central-sender-mode - if: ${{ steps.sender-config.outputs.use_central != 'true' }} 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 }} - sender_mode: ${{ steps.sender-config.outputs.send_action_mode }} - # 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