CI/CD Reference
Technical reference for running Agenda Panda inside CI/CD pipelines.
Looking for the acquisition-style walkthrough first? Start with the public CI/CD guide.
Quick Start
Section titled “Quick Start”- Create an API key in Settings
- Add it as a secret (
AP_API_KEY) in your CI system - Use the GitHub Action or raw CLI
- Pass
--projectand--connectionexplicitly when your automation should not depend on mutable local defaults
GitHub Action
Section titled “GitHub Action”- uses: agendapanda/post-action@v1 with: api-key: ${{ secrets.AP_API_KEY }} content: "We just shipped v2.0!"Raw CLI (any CI system)
Section titled “Raw CLI (any CI system)”curl -fsSL https://agendapanda.com/install.sh | bashAP_API_KEY=$AP_API_KEY ap post "Deployed to production" --project "$AP_PROJECT" --connection linkedinCalendar sync in automation
Section titled “Calendar sync in automation”Keep a calendar.json in your repo and sync on every push:
- uses: agendapanda/post-action@v1 with: api-key: ${{ secrets.AP_API_KEY }} calendar-file: "./calendar.json"With raw CLI commands:
curl -fsSL https://agendapanda.com/install.sh | bashAP_API_KEY=$AP_API_KEY ap calendar sync --file calendar.json --project "$AP_PROJECT" --dry-runAP_API_KEY=$AP_API_KEY ap calendar sync --file calendar.json --project "$AP_PROJECT" --delete-missingSee the Calendar as Code guide for the JSON format.
GitHub release workflow
Section titled “GitHub release workflow”Use GitHub Actions when you want each release to create a reviewable Agenda Panda release packet automatically instead of posting immediately.
What this workflow does
Section titled “What this workflow does”- Runs on
release.publishedor a manualworkflow_dispatch - Supports release tags that start with
cli-v,web-v, orwebsite-v - Normalizes both
web-v*andwebsite-v*to thewebsiterelease kind used in the draft payload - Creates a release packet in Agenda Panda with social drafts plus internal draft artifacts for review before publishing
GitHub setup
Section titled “GitHub setup”- Create an API key in Settings
- Add these repository secrets in GitHub:
AP_API_KEY: API key with access to your workspaceAP_PROJECT_ID: target workspace/project IDOPENAI_API_KEY: optional but recommended if you want model-generated release packets instead of deterministic fallback copy
- Add these optional GitHub values if you want more control:
AP_SOCIAL_CONNECTION_ID(secret): prebind the draft to a specific social connectionAP_API_URL(repository variable): defaults tohttps://agendapanda.comOPENAI_MODEL(repository variable): model used for packet generation, for examplegpt-5-miniRELEASE_DOC_PATHS(repository variable): comma-separated repo files to feed into packet generationRELEASE_SOCIAL_CHANNELS(repository variable): comma-separated platforms to generate social drafts for, for examplelinkedin,xRELEASE_PROMPT_VERSION(repository variable): prompt/template version label for traceabilityRELEASE_DRAFT_TIME_UTC(repository variable): target UTC time inHH:MM:SSZ, default14:00:00ZRELEASE_DRAFT_PLATFORM(repository variable): legacy single-platform fallback ifRELEASE_SOCIAL_CHANNELSis unset
- Add the workflow below to
.github/workflows/release-draft.ymlin your repo
If you skip AP_SOCIAL_CONNECTION_ID, the packet is still created. Any generated social drafts stay unbound so someone can choose the target connection during review.
Example workflow
Section titled “Example workflow”This repo uses the same pattern in .github/workflows/release-dogfood-draft.yml:
name: Release Draft to Agenda Panda
on: release: types: [published] workflow_dispatch: inputs: release_kind: description: 'Release kind' type: choice options: - cli - website required: true release_version: description: 'Version label to include (for example 1.2.3)' required: true release_name: description: 'Optional release title override' required: false release_notes: description: 'Optional release notes or highlights override' required: false release_url: description: 'Optional release URL override' required: false schedule_days_ahead: description: 'How many days ahead to schedule (0 = same day, 1 = next day)' required: false default: '1'
jobs: create-draft: runs-on: ubuntu-latest if: ${{ github.event_name == 'workflow_dispatch' || startsWith(github.event.release.tag_name, 'cli-v') || startsWith(github.event.release.tag_name, 'web-v') || startsWith(github.event.release.tag_name, 'website-v') }} steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20
- name: Resolve release metadata id: release run: | if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then echo "kind=${{ inputs.release_kind }}" >> "$GITHUB_OUTPUT" echo "version=${{ inputs.release_version }}" >> "$GITHUB_OUTPUT" echo "name=${{ inputs.release_name }}" >> "$GITHUB_OUTPUT" echo "notes<<EOF" >> "$GITHUB_OUTPUT" echo "${{ inputs.release_notes }}" >> "$GITHUB_OUTPUT" echo "EOF" >> "$GITHUB_OUTPUT" echo "url=${{ inputs.release_url }}" >> "$GITHUB_OUTPUT" echo "tag=" >> "$GITHUB_OUTPUT" echo "days=${{ inputs.schedule_days_ahead }}" >> "$GITHUB_OUTPUT" exit 0 fi
TAG="${{ github.event.release.tag_name }}" NAME="${{ github.event.release.name }}" NOTES="${{ github.event.release.body }}" URL="${{ github.event.release.html_url }}"
if [[ "$TAG" == cli-v* ]]; then KIND="cli" VERSION="${TAG#cli-v}" elif [[ "$TAG" == web-v* ]]; then KIND="website" VERSION="${TAG#web-v}" elif [[ "$TAG" == website-v* ]]; then KIND="website" VERSION="${TAG#website-v}" else echo "Unsupported release tag: $TAG" exit 1 fi
echo "kind=$KIND" >> "$GITHUB_OUTPUT" echo "version=$VERSION" >> "$GITHUB_OUTPUT" echo "name=$NAME" >> "$GITHUB_OUTPUT" echo "notes<<EOF" >> "$GITHUB_OUTPUT" echo "$NOTES" >> "$GITHUB_OUTPUT" echo "EOF" >> "$GITHUB_OUTPUT" echo "url=$URL" >> "$GITHUB_OUTPUT" echo "tag=$TAG" >> "$GITHUB_OUTPUT" echo "days=1" >> "$GITHUB_OUTPUT"
- name: Create release packet in Agenda Panda env: AP_API_URL: ${{ vars.AP_API_URL }} AP_API_KEY: ${{ secrets.AP_API_KEY }} AP_PROJECT_ID: ${{ secrets.AP_PROJECT_ID }} AP_SOCIAL_CONNECTION_ID: ${{ secrets.AP_SOCIAL_CONNECTION_ID }} OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} OPENAI_MODEL: ${{ vars.OPENAI_MODEL }} RELEASE_KIND: ${{ steps.release.outputs.kind }} RELEASE_VERSION: ${{ steps.release.outputs.version }} RELEASE_NAME: ${{ steps.release.outputs.name }} RELEASE_NOTES: ${{ steps.release.outputs.notes }} RELEASE_URL: ${{ steps.release.outputs.url }} RELEASE_TAG: ${{ steps.release.outputs.tag }} RELEASE_DOC_PATHS: ${{ vars.RELEASE_DOC_PATHS }} RELEASE_SOCIAL_CHANNELS: ${{ vars.RELEASE_SOCIAL_CHANNELS }} RELEASE_PROMPT_VERSION: ${{ vars.RELEASE_PROMPT_VERSION }} SCHEDULE_DAYS_AHEAD: ${{ steps.release.outputs.days }} SCHEDULE_TIME_UTC: ${{ vars.RELEASE_DRAFT_TIME_UTC }} POST_PLATFORM: ${{ vars.RELEASE_DRAFT_PLATFORM }} POST_SOURCE: github_release_intelligence run: node scripts/create-release-packet.mjsManual inputs and scheduling
Section titled “Manual inputs and scheduling”release_kind: usecliorwebsitefor manual runsrelease_version: the version label that appears in the draft copyrelease_name,release_notes, andrelease_url: optional overrides for the generated release packetschedule_days_ahead:0for same-day drafts,1for next-day drafts, default1RELEASE_SOCIAL_CHANNELS: preferred way to generate multiple social drafts, such aslinkedin,xRELEASE_DRAFT_TIME_UTC: GitHub repository variable for the target UTC publish timeRELEASE_DRAFT_PLATFORM: single-platform fallback for older setupsRELEASE_DOC_PATHS: repo files that provide product and positioning context to the packet generator
If you run the helper script directly outside GitHub Actions, it also accepts SCHEDULE_TIME_UTC and POST_PLATFORM as equivalent environment variables.
Review flow
Section titled “Review flow”- The workflow creates a release packet in Agenda Panda. It does not auto-publish.
- Social artifacts are also synced into scheduled social drafts when possible so they can move through the existing review and publish flow.
- Open the packet or the linked drafts in Agenda Panda, confirm the copy and target connection, then publish when ready.