[GH-ISSUE #47] Add beta-groups add/remove testers #9

Closed
opened 2026-02-26 21:32:44 +03:00 by kerem · 3 comments
Owner

Originally created by @rudrankriyam on GitHub (Jan 23, 2026).
Original GitHub issue: https://github.com/rudrankriyam/App-Store-Connect-CLI/issues/47

Summary

Add commands to manage beta tester membership for a beta group.

API endpoints

CLI

  • asc beta-groups add-testers --group "GROUP_ID" --tester "TESTER_ID[,TESTER_ID...]"
  • asc beta-groups remove-testers --group "GROUP_ID" --tester "TESTER_ID[,TESTER_ID...]"

Output

  • JSON minified default; --output table|markdown; --pretty for JSON.

Tests

  • Relationship POST/DELETE client tests
  • CLI tests for validation and payload shaping
Originally created by @rudrankriyam on GitHub (Jan 23, 2026). Original GitHub issue: https://github.com/rudrankriyam/App-Store-Connect-CLI/issues/47 ## Summary Add commands to manage beta tester membership for a beta group. ## API endpoints - `POST /v1/betaGroups/{id}/relationships/betaTesters` (add testers) — https://developer.apple.com/documentation/appstoreconnectapi/add_beta_testers_to_a_beta_group - `DELETE /v1/betaGroups/{id}/relationships/betaTesters` (remove testers) — https://developer.apple.com/documentation/appstoreconnectapi/remove_beta_testers_from_a_beta_group ## CLI - `asc beta-groups add-testers --group "GROUP_ID" --tester "TESTER_ID[,TESTER_ID...]"` - `asc beta-groups remove-testers --group "GROUP_ID" --tester "TESTER_ID[,TESTER_ID...]"` ## Output - JSON minified default; `--output table|markdown`; `--pretty` for JSON. ## Tests - Relationship POST/DELETE client tests - CLI tests for validation and payload shaping
kerem closed this issue 2026-02-26 21:32:44 +03:00
Author
Owner

@rudrankriyam commented on GitHub (Jan 23, 2026):

@cursor Please implement this issue.

Implementation Guide

1. Add Commands to cmd/beta.go

Add two new subcommands to BetaGroupsCommand():

BetaGroupsAddTestersCommand()
BetaGroupsRemoveTestersCommand()

2. Add Client Methods in internal/asc/client.go

// AddBetaTestersToGroup adds testers to a beta group
// POST /v1/betaGroups/{id}/relationships/betaTesters
func (c *Client) AddBetaTestersToGroup(ctx context.Context, groupID string, testerIDs []string) error {
    url := fmt.Sprintf("%s/betaGroups/%s/relationships/betaTesters", baseURL, groupID)
    payload := RelationshipRequest{
        Data: make([]RelationshipData, len(testerIDs)),
    }
    for i, id := range testerIDs {
        payload.Data[i] = RelationshipData{Type: "betaTesters", ID: id}
    }
    // POST request
}

// RemoveBetaTestersFromGroup removes testers from a beta group
// DELETE /v1/betaGroups/{id}/relationships/betaTesters
func (c *Client) RemoveBetaTestersFromGroup(ctx context.Context, groupID string, testerIDs []string) error {
    // Similar to above but DELETE with body
}

Add relationship types if not present:

type RelationshipRequest struct {
    Data []RelationshipData `json:"data"`
}

type RelationshipData struct {
    Type string `json:"type"`
    ID   string `json:"id"`
}

3. CLI Flags

For add-testers:

  • --group (required, group ID)
  • --tester (required, comma-separated tester IDs)

For remove-testers:

  • --group (required, group ID)
  • --tester (required, comma-separated tester IDs)

4. Parse Comma-Separated IDs

func parseCommaSeparatedIDs(input string) []string {
    parts := strings.Split(input, ",")
    result := make([]string, 0, len(parts))
    for _, p := range parts {
        if trimmed := strings.TrimSpace(p); trimmed != "" {
            result = append(result, trimmed)
        }
    }
    return result
}

5. Testing

Unit tests in cmd/commands_test.go:

{"beta-groups add-testers missing group", []string{"beta-groups", "add-testers"}, ...}
{"beta-groups add-testers missing tester", []string{"beta-groups", "add-testers", "--group", "X"}, ...}
{"beta-groups remove-testers missing confirm", ...}  // if you add --confirm

Client tests in internal/asc/client_http_test.go:

  • Test relationship payload structure
  • Test comma-separated parsing

Live API test (use FoundationLab groups):

# First get a tester ID
./asc beta-testers list --app 6747745091 --limit 1

# Then test (use Beta group: e601afa2-e59f-472f-9280-e35ab2f9bbe9)
./asc beta-groups add-testers --group "GROUP_ID" --tester "TESTER_ID"
./asc beta-groups remove-testers --group "GROUP_ID" --tester "TESTER_ID"

6. Success Output

Print success message to stderr:

fmt.Fprintf(os.Stderr, "Successfully added %d tester(s) to group %s\n", len(testerIDs), groupID)

7. Code Standards

  • Validate at least one tester ID provided
  • Use strings.TrimSpace() on group and all tester IDs
  • Handle API errors gracefully (e.g., tester already in group)
  • Run make format && make lint && make test before committing
<!-- gh-comment-id:3792263223 --> @rudrankriyam commented on GitHub (Jan 23, 2026): @cursor Please implement this issue. ## Implementation Guide ### 1. Add Commands to `cmd/beta.go` Add two new subcommands to `BetaGroupsCommand()`: ```go BetaGroupsAddTestersCommand() BetaGroupsRemoveTestersCommand() ``` ### 2. Add Client Methods in `internal/asc/client.go` ```go // AddBetaTestersToGroup adds testers to a beta group // POST /v1/betaGroups/{id}/relationships/betaTesters func (c *Client) AddBetaTestersToGroup(ctx context.Context, groupID string, testerIDs []string) error { url := fmt.Sprintf("%s/betaGroups/%s/relationships/betaTesters", baseURL, groupID) payload := RelationshipRequest{ Data: make([]RelationshipData, len(testerIDs)), } for i, id := range testerIDs { payload.Data[i] = RelationshipData{Type: "betaTesters", ID: id} } // POST request } // RemoveBetaTestersFromGroup removes testers from a beta group // DELETE /v1/betaGroups/{id}/relationships/betaTesters func (c *Client) RemoveBetaTestersFromGroup(ctx context.Context, groupID string, testerIDs []string) error { // Similar to above but DELETE with body } ``` Add relationship types if not present: ```go type RelationshipRequest struct { Data []RelationshipData `json:"data"` } type RelationshipData struct { Type string `json:"type"` ID string `json:"id"` } ``` ### 3. CLI Flags For `add-testers`: - `--group` (required, group ID) - `--tester` (required, comma-separated tester IDs) For `remove-testers`: - `--group` (required, group ID) - `--tester` (required, comma-separated tester IDs) ### 4. Parse Comma-Separated IDs ```go func parseCommaSeparatedIDs(input string) []string { parts := strings.Split(input, ",") result := make([]string, 0, len(parts)) for _, p := range parts { if trimmed := strings.TrimSpace(p); trimmed != "" { result = append(result, trimmed) } } return result } ``` ### 5. Testing **Unit tests** in `cmd/commands_test.go`: ```go {"beta-groups add-testers missing group", []string{"beta-groups", "add-testers"}, ...} {"beta-groups add-testers missing tester", []string{"beta-groups", "add-testers", "--group", "X"}, ...} {"beta-groups remove-testers missing confirm", ...} // if you add --confirm ``` **Client tests** in `internal/asc/client_http_test.go`: - Test relationship payload structure - Test comma-separated parsing **Live API test** (use FoundationLab groups): ```bash # First get a tester ID ./asc beta-testers list --app 6747745091 --limit 1 # Then test (use Beta group: e601afa2-e59f-472f-9280-e35ab2f9bbe9) ./asc beta-groups add-testers --group "GROUP_ID" --tester "TESTER_ID" ./asc beta-groups remove-testers --group "GROUP_ID" --tester "TESTER_ID" ``` ### 6. Success Output Print success message to stderr: ```go fmt.Fprintf(os.Stderr, "Successfully added %d tester(s) to group %s\n", len(testerIDs), groupID) ``` ### 7. Code Standards - Validate at least one tester ID provided - Use `strings.TrimSpace()` on group and all tester IDs - Handle API errors gracefully (e.g., tester already in group) - Run `make format && make lint && make test` before committing
Author
Owner

@cursor[bot] commented on GitHub (Jan 23, 2026):

Summary:

  • Added beta-groups add-testers/remove-testers commands with validation, trimming, and success messaging.
  • Implemented client relationship payload types and add/remove tester relationship methods.
  • Added CLI validation + parsing tests and client HTTP payload/error-path tests.

Tests:

  • export PATH="$(go env GOPATH)/bin:$PATH" && make format && make lint && make test

Notes:

  • Installed gofumpt via go install mvdan.cc/gofumpt@latest (ensure $(go env GOPATH)/bin is on PATH for make format).
  • Live API tests not run.

View PR
Open in Cursor Open in Web

<!-- gh-comment-id:3792263532 --> @cursor[bot] commented on GitHub (Jan 23, 2026): Summary: - Added `beta-groups add-testers`/`remove-testers` commands with validation, trimming, and success messaging. - Implemented client relationship payload types and add/remove tester relationship methods. - Added CLI validation + parsing tests and client HTTP payload/error-path tests. Tests: - `export PATH="$(go env GOPATH)/bin:$PATH" && make format && make lint && make test` Notes: - Installed `gofumpt` via `go install mvdan.cc/gofumpt@latest` (ensure `$(go env GOPATH)/bin` is on PATH for `make format`). - Live API tests not run. <a href="https://github.com/rudrankriyam/App-Store-Connect-CLI/pull/55"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/view-pr-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/view-pr-light.svg"><img alt="View PR" src="https://cursor.com/view-pr-light.svg"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-06447577-d440-4feb-a487-a482f6f6e4c6"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/open-in-cursor-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/open-in-cursor-light.svg"><img alt="Open in Cursor" src="https://cursor.com/open-in-cursor.svg"></picture></a>&nbsp;<a href="https://cursor.com/agents?id=bc-06447577-d440-4feb-a487-a482f6f6e4c6"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/open-in-web-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/open-in-web-light.svg"><img alt="Open in Web" src="https://cursor.com/open-in-web.svg"></picture></a>
Author
Owner

@rudrankriyam commented on GitHub (Jan 23, 2026):

Implemented in PR #55 - beta-groups add-testers and remove-testers commands.

<!-- gh-comment-id:3792501230 --> @rudrankriyam commented on GitHub (Jan 23, 2026): Implemented in PR #55 - beta-groups add-testers and remove-testers commands.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/App-Store-Connect-CLI#9
No description provided.