Skip to content
Closed
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
126 changes: 126 additions & 0 deletions .github/actions/agent-status-comment/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
name: Agent Status Comment
description: >-
Post or update a status comment on an issue or PR for a fullsend agent
workflow run. Start comments include a run-specific HTML marker. On
completion, the start comment is edited in place if it is still the
last comment; otherwise a new completion comment is posted. Cancelled
runs delete their start comment to avoid stale "in progress" messages.

inputs:
description:
description: >-
Human-readable action phrase (e.g. "Reviewing this PR"). Used as-is for
start comments; completion comments prepend "Finished". Must be a
hardcoded literal — do not pass user-controlled content.
required: true
number:
description: Issue or PR number to comment on
required: true
repo:
description: Repository full name (owner/repo) to comment on
required: true
sha:
description: Commit SHA the workflow is running against
required: true
token:
description: GitHub token with issues:write permission
required: true
status:
description: >-
Workflow job status (success/failure/cancelled). When set, updates or
posts a completion comment; when empty, posts a start comment.
required: false
default: ''

runs:
using: composite
steps:
- name: Post status comment
shell: bash
env:
GH_TOKEN: ${{ inputs.token }}
DESCRIPTION: ${{ inputs.description }}
NUMBER: ${{ inputs.number }}
REPO: ${{ inputs.repo }}
SHA: ${{ inputs.sha }}
STATUS: ${{ inputs.status }}
run: |
set -euo pipefail

if [[ -z "${NUMBER}" || "${NUMBER}" == "null" ]]; then
echo "::notice::No issue/PR number — skipping status comment"
exit 0
fi

MARKER="<!-- fullsend:agent-status:${GITHUB_RUN_ID} -->"
RUN_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
SHORT_SHA="${SHA:0:7}"
TIMESTAMP=$(date -u +'%-I:%M %p UTC')

find_start_comment() {
gh api "repos/${REPO}/issues/${NUMBER}/comments" \
--paginate \
--jq "[.[] | select(.body | contains(\"${MARKER}\")) | .id] | first" \
2>/dev/null || true
}

if [[ -z "${STATUS}" ]]; then
# Post start comment
printf -v BODY '%s\n%s\n%s' \
"${MARKER}" \
"🤖 ${DESCRIPTION} · Started ${TIMESTAMP}" \
"Commit: \`${SHORT_SHA}\` · [View workflow run →](${RUN_URL})"
gh issue comment "${NUMBER}" --repo "${REPO}" --body "${BODY}"

elif [[ "${STATUS}" == "cancelled" ]]; then
Comment thread
ggallen marked this conversation as resolved.
# Cancelled (superseded) run — delete the start comment.
COMMENT_ID=$(find_start_comment)
if [[ -n "${COMMENT_ID}" && "${COMMENT_ID}" != "null" ]]; then
gh api -X DELETE "repos/${REPO}/issues/comments/${COMMENT_ID}" 2>/dev/null || true
fi

else
# Completion — edit in place if start comment is still last,
# otherwise post a new comment.
case "${STATUS}" in
success) STATUS_LABEL="✅ Success" ;;
failure) STATUS_LABEL="❌ Failure" ;;
*) STATUS_LABEL="❓ ${STATUS}" ;;
esac

COMMENT_ID=$(find_start_comment)

# Extract start time from the existing comment body
START_TIME=""
if [[ -n "${COMMENT_ID}" && "${COMMENT_ID}" != "null" ]]; then
START_TIME=$(gh api "repos/${REPO}/issues/comments/${COMMENT_ID}" \
--jq '.body' 2>/dev/null \
| grep -oP 'Started \K[0-9]+:[0-9]+ [AP]M UTC' || true)
fi

if [[ -n "${START_TIME}" ]]; then
TIME_PART=" · Started ${START_TIME} · Completed ${TIMESTAMP}"
else
TIME_PART=" · Completed ${TIMESTAMP}"
fi

printf -v BODY '%s\n%s\n%s' \
"${MARKER}" \
"🤖 Finished ${DESCRIPTION} · ${STATUS_LABEL}${TIME_PART}" \
"Commit: \`${SHORT_SHA}\` · [View workflow run →](${RUN_URL})"

if [[ -n "${COMMENT_ID}" && "${COMMENT_ID}" != "null" ]]; then
# Check if start comment is the last comment on the issue/PR
LAST_COMMENT_ID=$(gh api "repos/${REPO}/issues/${NUMBER}/comments?per_page=1&direction=desc" \
--jq '.[0].id' 2>/dev/null || true)
if [[ "${COMMENT_ID}" == "${LAST_COMMENT_ID}" ]]; then
gh api -X PATCH "repos/${REPO}/issues/comments/${COMMENT_ID}" \
-f body="${BODY}" 2>/dev/null || true
else
gh issue comment "${NUMBER}" --repo "${REPO}" --body "${BODY}"
fi
else
# Start comment not found — post fresh
gh issue comment "${NUMBER}" --repo "${REPO}" --body "${BODY}"
fi
fi
27 changes: 27 additions & 0 deletions .github/workflows/reusable-code.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ jobs:
fetch-depth: 0
persist-credentials: false

- name: Record target commit SHA
id: target-sha
run: echo "sha=$(git -C target-repo rev-parse HEAD)" >> "$GITHUB_OUTPUT"

- name: Validate inputs
env:
ISSUE_NUMBER: ${{ fromJSON(inputs.event_payload).issue.number }}
Expand All @@ -142,6 +146,17 @@ jobs:
CODE_ISSUE_NUMBER: ${{ fromJSON(inputs.event_payload).issue.number }}
run: bash .github/scripts/setup-agent-env.sh

- name: Post start comment
if: steps.app-token.outputs.token != ''
continue-on-error: true
uses: fullsend-ai/fullsend/.github/actions/agent-status-comment@v0
with:
description: Implementing changes and creating a PR
number: ${{ fromJSON(inputs.event_payload).issue.number }}
repo: ${{ inputs.source_repo }}
sha: ${{ steps.target-sha.outputs.sha }}
token: ${{ steps.app-token.outputs.token }}

- name: Run code agent
uses: fullsend-ai/fullsend@v0
env:
Expand All @@ -154,3 +169,15 @@ jobs:
with:
agent: code
version: ${{ inputs.fullsend_version }}

- name: Post completion comment
if: always() && steps.app-token.outputs.token != ''
continue-on-error: true
uses: fullsend-ai/fullsend/.github/actions/agent-status-comment@v0
with:
description: Implementing changes and creating a PR
number: ${{ fromJSON(inputs.event_payload).issue.number }}
repo: ${{ inputs.source_repo }}
sha: ${{ steps.target-sha.outputs.sha }}
token: ${{ steps.app-token.outputs.token }}
status: ${{ job.status }}
23 changes: 23 additions & 0 deletions .github/workflows/reusable-fix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,17 @@ jobs:
FIX_REPO_FULL_NAME: ${{ inputs.source_repo }}
run: bash .github/scripts/setup-agent-env.sh

- name: Post start comment
if: steps.app-token.outputs.token != ''
continue-on-error: true
uses: fullsend-ai/fullsend/.github/actions/agent-status-comment@v0
with:
description: Addressing review feedback on this PR
number: ${{ steps.context.outputs.pr_number }}
repo: ${{ inputs.source_repo }}
sha: ${{ steps.pre-agent.outputs.head }}
token: ${{ steps.app-token.outputs.token }}

- name: Run fix agent
uses: fullsend-ai/fullsend@v0
env:
Expand All @@ -356,3 +367,15 @@ jobs:
with:
agent: fix
version: ${{ inputs.fullsend_version }}

- name: Post completion comment
if: always() && steps.app-token.outputs.token != ''
continue-on-error: true
uses: fullsend-ai/fullsend/.github/actions/agent-status-comment@v0
with:
description: Addressing review feedback on this PR
number: ${{ steps.context.outputs.pr_number }}
repo: ${{ inputs.source_repo }}
sha: ${{ steps.pre-agent.outputs.head }}
token: ${{ steps.app-token.outputs.token }}
status: ${{ job.status }}
27 changes: 27 additions & 0 deletions .github/workflows/reusable-retro.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ jobs:
fetch-depth: 1
persist-credentials: false

- name: Record target commit SHA
id: target-sha
run: echo "sha=$(git -C target-repo rev-parse HEAD)" >> "$GITHUB_OUTPUT"

- name: Setup GCP and prepare credentials
uses: fullsend-ai/fullsend/.github/actions/setup-gcp@v0
with:
Expand All @@ -131,6 +135,17 @@ jobs:
RETRO_CLOUD_ML_REGION: ${{ inputs.gcp_region }}
run: bash .github/scripts/setup-agent-env.sh

- name: Post start comment
if: steps.app-token.outputs.token != ''
continue-on-error: true
uses: fullsend-ai/fullsend/.github/actions/agent-status-comment@v0
with:
description: Running a retrospective
number: ${{ fromJSON(inputs.event_payload).pull_request.number || fromJSON(inputs.event_payload).issue.number }}
repo: ${{ inputs.source_repo }}
sha: ${{ steps.target-sha.outputs.sha }}
token: ${{ steps.app-token.outputs.token }}

- name: Run retro agent
uses: fullsend-ai/fullsend@v0
env:
Expand All @@ -142,3 +157,15 @@ jobs:
with:
agent: retro
version: ${{ inputs.fullsend_version }}

- name: Post completion comment
if: always() && steps.app-token.outputs.token != ''
continue-on-error: true
uses: fullsend-ai/fullsend/.github/actions/agent-status-comment@v0
with:
description: Running a retrospective
number: ${{ fromJSON(inputs.event_payload).pull_request.number || fromJSON(inputs.event_payload).issue.number }}
repo: ${{ inputs.source_repo }}
sha: ${{ steps.target-sha.outputs.sha }}
token: ${{ steps.app-token.outputs.token }}
status: ${{ job.status }}
27 changes: 27 additions & 0 deletions .github/workflows/reusable-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ jobs:
fetch-depth: 1
persist-credentials: false

- name: Record target commit SHA
id: target-sha
run: echo "sha=$(git -C target-repo rev-parse HEAD)" >> "$GITHUB_OUTPUT"

- name: Pre-fetch prior review context
id: prior-review
env:
Expand Down Expand Up @@ -144,6 +148,17 @@ jobs:
REVIEW_CLOUD_ML_REGION: ${{ inputs.gcp_region }}
run: bash .github/scripts/setup-agent-env.sh

- name: Post start comment
if: steps.app-token.outputs.token != ''
continue-on-error: true
uses: fullsend-ai/fullsend/.github/actions/agent-status-comment@v0
with:
description: Reviewing this PR
number: ${{ fromJSON(inputs.event_payload).pull_request.number || fromJSON(inputs.event_payload).issue.number }}
repo: ${{ inputs.source_repo }}
sha: ${{ steps.target-sha.outputs.sha }}
token: ${{ steps.app-token.outputs.token }}

- name: Run review agent
uses: fullsend-ai/fullsend@v0
env:
Expand All @@ -158,3 +173,15 @@ jobs:
with:
agent: review
version: ${{ inputs.fullsend_version }}

- name: Post completion comment
if: always() && steps.app-token.outputs.token != ''
continue-on-error: true
uses: fullsend-ai/fullsend/.github/actions/agent-status-comment@v0
with:
description: Reviewing this PR
number: ${{ fromJSON(inputs.event_payload).pull_request.number || fromJSON(inputs.event_payload).issue.number }}
repo: ${{ inputs.source_repo }}
sha: ${{ steps.target-sha.outputs.sha }}
token: ${{ steps.app-token.outputs.token }}
status: ${{ job.status }}
27 changes: 27 additions & 0 deletions .github/workflows/reusable-triage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ jobs:
fetch-depth: 1
persist-credentials: false

- name: Record target commit SHA
id: target-sha
run: echo "sha=$(git -C target-repo rev-parse HEAD)" >> "$GITHUB_OUTPUT"

- name: Setup GCP and prepare credentials
uses: fullsend-ai/fullsend/.github/actions/setup-gcp@v0
with:
Expand All @@ -131,10 +135,33 @@ jobs:
TRIAGE_CLOUD_ML_REGION: ${{ inputs.gcp_region }}
run: bash .github/scripts/setup-agent-env.sh

- name: Post start comment
if: steps.app-token.outputs.token != ''
continue-on-error: true
uses: fullsend-ai/fullsend/.github/actions/agent-status-comment@v0
with:
description: Triaging this issue
number: ${{ fromJSON(inputs.event_payload).issue.number }}
repo: ${{ inputs.source_repo }}
sha: ${{ steps.target-sha.outputs.sha }}
token: ${{ steps.app-token.outputs.token }}

- name: Run triage agent
uses: fullsend-ai/fullsend@v0
env:
GITHUB_ISSUE_URL: ${{ fromJSON(inputs.event_payload).issue.html_url }}
with:
agent: triage
version: ${{ inputs.fullsend_version }}

- name: Post completion comment
if: always() && steps.app-token.outputs.token != ''
continue-on-error: true
uses: fullsend-ai/fullsend/.github/actions/agent-status-comment@v0
with:
description: Triaging this issue
number: ${{ fromJSON(inputs.event_payload).issue.number }}
repo: ${{ inputs.source_repo }}
sha: ${{ steps.target-sha.outputs.sha }}
token: ${{ steps.app-token.outputs.token }}
status: ${{ job.status }}
Loading
Loading