Add campaign CRUD client methods and check management#611
Open
jamescarr wants to merge 9 commits intoOpsLevel:mainfrom
Open
Add campaign CRUD client methods and check management#611jamescarr wants to merge 9 commits intoOpsLevel:mainfrom
jamescarr wants to merge 9 commits intoOpsLevel:mainfrom
Conversation
4 tasks
7877f45 to
ea1f16b
Compare
Adds GetCampaign, CreateCampaign, UpdateCampaign, DeleteCampaign, ScheduleCampaign, and UnscheduleCampaign client methods along with their corresponding input and payload types. These are needed by the terraform-provider-opslevel campaign resource. Made-with: Cursor
ea1f16b to
2fc76ed
Compare
The OpsLevel API doesn't have a campaignSchedule mutation. Scheduling is done by passing startDate/targetDate in campaignCreate/campaignUpdate. Removes ScheduleCampaign method and CampaignScheduleUpdateInput. Made-with: Cursor
The OpsLevel API uses a separate campaignScheduleUpdate mutation (not campaignSchedule, and not fields on create/update inputs). Also uses generic DeleteInput for campaignDelete/campaignUnschedule. Made-with: Cursor
Made-with: Cursor
Replace CheckIdsToCopy on CampaignCreateInput with a dedicated CopyChecksToCampaign method that calls the checksCopyToCampaign GraphQL mutation. This is the correct API for associating rubric checks with a campaign after creation. Changes: - Add ChecksCopyToCampaignInput and ChecksCopyToCampaignPayload types - Add Client.CopyChecksToCampaign method - Remove CheckIdsToCopy from CampaignCreateInput (not a real API field) - Add comprehensive tests for all campaign CRUD operations (Create, Get, Update, Delete, Schedule, Unschedule, CopyChecks) - Add test fixtures in campaigns.tpl for all operations Made-with: Cursor
Adds a lightweight query for fetching a campaign's checks (id + name only) to enable matching and deleting campaign checks when rubric check IDs are removed from the Terraform resource's check_ids list. Made-with: Cursor
Author
|
Alright, tested a full path of create, update and delete. required_providers {
opslevel = {
source = "jamescarr/opslevel"
version = "1.10.9"
}resource "opslevel_campaign" "demo_may_rollout" {
name = "June 2026 Demo Checks Rollout (Revised)"
owner_id = data.opslevel_team.staff.id
filter_id = data.opslevel_filter.tier1.id
start_date = "2026-06-15"
target_date = "2026-08-15"
check_ids = [
opslevel_check_manual.demo_secret_rotation.id,
opslevel_check_manual.demo_dependency_scanning.id,
opslevel_check_manual.demo_error_budget.id,
]
project_brief = <<-EOT
## Overview
Three checks are being enabled on **June 15, 2026** as part of the
revised sandbox demo rollout. All Tier 1 services must pass by **August 15, 2026**.
## Checks Included
| Check | Category | What it verifies |
|-------|----------|-----------------|
| DEMO-001 | Security | Secrets rotated every 90 days |
| DEMO-002 | Security | Dependency vulnerability scanning |
| DEMO-003 | Reliability | Error budget defined and tracked |
## What you need to do
1. Review each check's notes for pass criteria
2. Implement any missing requirements
3. Mark manual checks as passing with a comment explaining evidence
## Resources
- [OpsLevel Checks as Code](https://engineering.index/guides/architecture/opslevel-checks/)
- Questions? Reach out in #service-opslevel
EOT
}Opslevel Output |
Adds a test verifying ListCampaignChecks returns an empty slice when a campaign has no checks, plus the supporting template. Made-with: Cursor
…cursive pagination Aligns GetCampaign with the empty-ID convention used by GetCategory, GetScorecard, etc. Converts ListCampaignChecks from iterative to recursive pagination to match the rest of the SDK. Made-with: Cursor
c154bf6 to
5795287
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Closes #612
Add full campaign lifecycle management to the Go SDK via GraphQL.
Problem
The OpsLevel GraphQL API exposes full campaign mutation support (
campaignCreate,campaignUpdate,campaignDelete,campaignScheduleUpdate,campaignUnschedule,campaignEnd) pluschecksCopyToCampaignfor associating checks, but the Go SDK only has aListCampaignsquery. There are no client methods for creating, reading, updating, deleting, scheduling, or managing campaign checks — which blocks the Terraform provider from managing campaigns as code.Solution
Input types (
input.go):Added GraphQL input structs matching the API schema:
CampaignCreateInput— name, ownerId, filterId, projectBrief, checkIdsToCopy, reminderCampaignUpdateInput— id + optional fields for name, ownerId, filterId, projectBrief, reminderCampaignScheduleUpdateInput— id, startDate, targetDateCampaignEndInput— id, checksToPromoteCampaignUnscheduleInput— idCampaignReminderInput— frequency, frequencyUnit, timeOfDay, timezone, channels, message, daysOfWeek, defaultSlackChannelChecksCopyToCampaignInput— campaignId, checkIdsPayload types (
payload.go):Added response types for each mutation:
CampaignCreatePayload,CampaignUpdatePayload,CampaignDeletePayload,CampaignScheduleUpdatePayload,CampaignUnschedulePayload,CampaignEndPayload,ChecksCopyToCampaignPayload.Client methods (
campaign.go):GetCampaign(id)account.campaign(id:)CreateCampaign(input)campaignCreateUpdateCampaign(input)campaignUpdateDeleteCampaign(id)campaignDeleteScheduleCampaign(input)campaignScheduleUpdateUnscheduleCampaign(id)campaignUnscheduleEndCampaign(input)campaignEndCopyChecksToCampaign(input)checksCopyToCampaignListCampaignChecks(id)account.campaign.checksAll methods follow the existing SDK patterns (
client.Mutate/client.Query+HandleErrors).GetCampaignuses theaccount { campaign(id: $id) }query path discovered via schema introspection.Tests (
campaign_test.go):Full test coverage for all new methods including edge cases:
CopyChecksToCampaignListCampaignChecks(with results and empty campaign)Checklist