SuperAPI AI Directory

testany-import-git

Testing & quality

View repository

Updated 10-16 08:43

About this skill

Testany Git Import

Batch-register test scripts from a Git repository as Testany platform cases, and thereafter keep them in sync with the repository via sync / switch / relation.

User input: $ARGUMENTS


Core concepts

Object Description
Connection Git platform identity obtained after a one-time OAuth authorization (currently supports GitHub). Under a GitHub connection there are several installation_bindings, each binding represents one GitHub App installation (owner/org + accessible repo scope).installation_id is a required argument for subsequently browsing repositories
Import History One import configuration: bound to a certain connection, a certain repo, a certain ref, determining the mapping of "these files ↔ these cases"
File Binding Under import history, the binding record of "one file ↔ one case"; it is the source of truth for that batch of cases on Testany
Sync Record Audit record of one sync action (per-file success/failure/skip)

import_mode (enum values must match exactly)

Essential difference: backend auto-diff vs user manual selection — not a scenario judgment like "how much of the repository content is tests".

  • managed_import: mirror the repository, automatic diff.confirm_git_sync triggers an incremental landing of mirror→binding; newly added files can also go through addFiles separately, and upstream deletions go through the two-phase sourceDeleted confirmation
  • sync_link: explicitly manage the binding set.Under the current phase, confirm_git_sync is unavailable, and binding set evolution uniformly goes through the two relation flows addFiles (new files) and sourceDeleted (upstream deletion).preview_git_sync is used here only to view "changes of already-bound files relative to last_synced_commit"

Selection advice: want peace of mind + trust the repository as source-of-truth → managed_import; want fine-grained control over which files enter the binding set each time → sync_link. Do not infer based on reasons like "whether the repository is pure tests".

sync_mode (enum values must match exactly)

  • latest: follow the HEAD of tracked_branch , automatically advancing on each sync
  • pinned_commit: pinned to a certain commit; to advance you must go through switchCommit

Operations quick reference

Intent Toolchain
See which Git connections I have testany_list_git_connections
Create a new GitHub connection testany_initiate_git_oauth → user completes in browser → poll list
Access token about to expire / already expired but refresh_token still exists testany_refresh_git_connection_scope(server-to-server, no browser needed)
Refresh_token is also broken / user actively disconnects / switches account testany_reauthorize_git_connection(returns authorize_url, requires the user to complete in the browser)
Connection-side repo selection / scope change testany_refresh_git_connection_scope(same entry point; it both refreshes the token and verifies the scope)
Delete connection testany_disconnect_git_connection
List accessible repositories testany_list_git_repositories(required installation_id)
Select branch / commit testany_list_git_branches / testany_list_git_commits
View repository directory / preview file testany_browse_git_tree / testany_preview_git_file
List / view / delete imports testany_list_git_imports / testany_get_git_import / testany_delete_git_import
Create new import testany_create_git_import
View / clear bindings testany_list_git_import_file_bindings / testany_delete_git_import_file_bindings
Scheduled sync (managed_import only) testany_preview_git_sync → testany_confirm_git_sync(sync_link in current phase not supported confirm_sync; use addFiles/sourceDeleted instead)
Replay failed sync (sync_link only) testany_retry_git_sync({sync_record_id})
Switch commit (requires sync_mode=pinned_commit) testany_preview_git_switch_commit → testany_confirm_git_switch_commit
Unpin, return to latest (requires sync_mode=pinned_commit) testany_preview_git_switch_mode → testany_confirm_git_switch_mode
Audit sync history testany_list_git_sync_records → testany_get_git_sync_record
Add new file (both managed_import and sync_link) testany_get_git_add_files_summary → _list_git_add_files_candidates → _confirm_git_add_files
Mark source deleted (both managed_import and sync_link) testany_get_git_source_deleted_summary → _list_..._candidates → _confirm_git_source_deleted
Webhook read / toggle / rotate testany_get_git_webhook_config / _update_git_webhook_config / _disable_git_webhook / _regenerate_git_webhook_secret

Phase 1: Connect Git platform

  1. testany_list_git_connections, find the connection for the target platform
  2. Ifthere is no connection → testany_initiate_git_oauth({platform: "github"}) get authorize_url, hand it to the user's browser to complete the GitHub App installation authorization (the agent cannot click for them; clearly tell them "come back and let me know when done"), then poll testany_list_git_connections until the new connection appears
  3. Ifthere is a connection, do ahealth check(see connection-health.md):
    • config layer:status == "connected_scope_ready" is what counts as healthy ⚠️ not the literal "ready"
    • credential layer:token_expires_at must be > now + 60s; otherwise first call testany_refresh_git_connection_scope to do a server-to-server refresh (without disturbing the user)
    • Check whether each installation_bindings[i].scope_verified_at is too old (>24h, optional refresh)
  4. Once healthy, from connection.installation_bindings[] pick the target installation_id

Common unhealthy states → quick fix path reference(for the full enumeration see connection-health.md):

status / symptom handling
connected_scope_ready but token_expires_at expired or nearing expiry refresh_connection_scope(server-to-server)
token_expired reauthorize_git_connection → browser
permission_changed First refresh_connection_scope; if that fails then reauthorize
authorized_no_installation Use scope_management_entry_url to have the user's browser install the installation
disconnected initiate_git_oauth reauthorize

Key discipline: do not just look at status. GitHub App access_token expires after 8h by default; when it expires, status is still connected_scope_ready(a lagging indicator), and only the next GitHub-API call will make the backend flip it to token_expired. Proactively using token_expires_at to judge can avoid one unnecessary failed retry.


Phase 2: Choose repository and ref

  1. testany_list_git_repositories({connection_id, installation_id, search?}) select owner/repo + repo_full_name
  2. then choose the frame of reference:
    • sync_mode=latest → testany_list_git_branches choose tracked_branch
    • sync_mode=pinned_commit → also need testany_list_git_commits to select the specific pinned_commit
  3. If you need to verify files, use testany_browse_git_tree + testany_preview_git_file
  4. Choose runtime:Directly call testany_filter_case_runtimes to get the list for the user to choose, do not first ask the user what language the test script is in. Most runtimes' executors are consistent; by default recommend CloudPrime-Default(or another CloudPrime series). After the user picks, use the corresponding runtime_uuid. Do not make the user memorize UUIDs.
  5. Call testany_get_tenant_config to get deployment_type, for Phase 3 to decide the selected_files default value of visibility . Session-level caching is sufficient.

Phase 3: Assemble selected_files and create import

Required fields

When calling testany_create_git_import :

Field When required
connection_id Always
installation_id Always
import_mode Always (managed_import or sync_link)
sync_mode Always (latest or pinned_commit)
tracked_branch Always (even in pinned_commit mode, still carry branch context)
pinned_commit Only sync_mode=pinned_commit
runtime_uuid Always
repo_full_name Always, in the form owner/repo
selected_files Both import_mode values are required, as the first-round seed of the binding set
root_path Required, pass "/"when taking the repo root; pass a relative path when taking a subdirectory
workspace_key Optional. As a compatibility default: when per-file does not provide workspace_keys and the case is restricted, use this as a fallback.Do not treat it as requiredMake the user choose from dozens of workspaces

selected_files how to assemble

For each file to include, provide one FileSelectionInput:

  • file_path:Relative to the repository root(not relative to root_path)
  • name: case name; if not provided, use the file name
  • executor:testany_browse_git_tree returned by entry.executor is the backend-recommended value; use it directly
  • trigger_method: required for multi-config executors (playwright / maven / gradle, etc.); see structure in testany://schema/import-git
  • case_labels: first testany_list_labels confirm it exists (if it does not exist, first testany_create_label)
  • visibility / is_private: see "Case visibility policy" below

Case visibility policy

visibility / is_private / workspace_keys rules are constrained by tenant deployment_type .For complete rules, error codes, and how to obtain them, see case-visibility-policy.md。

Points specific to the Import path:

  1. Phase 2 has already called testany_get_tenant_config; here directly use the cached deployment_type to decide the per-file visibility default value
  2. Default policy:
    • deployment_type=1 → per-file visibility: "global", no need for workspace_keys, and no need for top-level workspace_key
    • deployment_type=2 → per-file visibility: "restricted" + workspace_keys: ["<key>"](or use top-level workspace_key as a fallback), because global is not allowed
  3. Top-level workspace_key is the fallback when per-file does not provide workspace_keys fallback for;type=1 does not need to be passed at all when using global
  4. The user insists on global under type=2 : explain the limitation to the user, downgrade to restricted; do not blindly retry

The backend currently treats private / workspace also as restricted a compatibility alias, but for agent wording and constructing payloads, uniformly using global | restricted is more robust.

After import: prompt that credential-type variables should be changed to be declared with secrets

Import will upload script files as cases, butis not responsible forfilling in environment_variablesfor cases (that is testany-case / testany-sync-case-env-from-source 's responsibility).

After the import is complete, if the script contains these naming patterns, proactively prompt the user to declare them as case_meta.environment_variables in type: secrets + secret_ref, rather than plaintext type: env:

  • *_PASSWORD / *_PWD
  • *_TOKEN / *_APIKEY / *_API_KEY
  • *_SECRET / *_KEY

After the user confirms secret_ref 's three fields (workspace_key / credential_safe_key / credential_key), the script can directly read the environment variable of the same name to obtain the credential value.


Phase 4: periodic sync

current-phase constraint:testany_confirm_git_sync currently only takes effect for managed_import ;sync_link binding evolution uniformly goes through addFiles / sourceDeleted. idempotency_key is automatically generated by MCP,do not manually pass UUIDs—unless you explicitly want deduplication across multiple calls.

managed_import

First obtain this round's testany_preview_git_sync, by Sync Authorization Decision Table verify actual differences against the current permission. Submit only when all differences are within the authorization and the pre-submission state has no conflicts; for differences already explicitly permitted, do not ask for confirmation again:

testany_confirm_git_sync({ import_history_id })

no_changes end; accidental deletions/additions must not be overridden by "just sync" or an old preview authorization. Managed confirm is applied based on the overall mirror difference and cannot pass file_selections to trim out unauthorized items. When exact candidates must be locked but the tool does not support it, stop and disclose it; do not fabricate snapshot parameters. After submission, verify the sync record, the actual commit, and failed_items.

sync_link

do not use confirm_git_sync. To evolve the binding set:

Intent Toolchain
extra files in the repository, need to add cases Phase 6 addFiles flow
files deleted from the repository, need to retire bindings Phase 6 sourceDeleted flow
replay failed items in an existing sync record testany_retry_git_sync({sync_record_id})

testany_preview_git_sync can still be called on sync_link, as an audit of "the current bound file's changes relative to last_synced_commit "—butit will not treat new files in the repository that have not yet been selected as candidates; new files are handled by the addFiles candidate list.

Failure Handling

SyncResult.failed_items If non-empty, report partial completion first; only when the current task has authorized retrying the same scope should you consider testany_retry_git_sync({sync_record_id}), and do not loop infinitely. Note:retry is only available for sync_link, and managed_import's confirm already handles per-file failures internally.


Phase 5: Switch (operates only on the sync_mode dimension)

the switch tool does not change import_mode(managed_import ↔ sync_link); it only operates on sync_mode. Both are preview → confirm two-phase: preview first to gather evidence; use the Sync Authorization Decision Table to distinguish authorized submissions from differences that genuinely require a new decision. Version switching or tracking mode permissions cannot be derived from an ordinary sync permission.

switchCommit — change the pinned commit

  • Preconditions:sync_mode=pinned_commit(both managed_import and sync_link are fine)
  • testany_preview_git_switch_commit({target_commit}) → _confirm_git_switch_commit({target_commit, file_selections?})
  • sync_link's confirm derives file_selectionsfrom preview.changes; managed_import's confirm does not accept file_selections(will return 400)
  • If preconditions are not met (for example, it is already latest), return ERR_SWITCH_NOT_ALLOWED

switchMode — unpin and return to following the branch HEAD

  • Semantics:sync_mode: pinned_commit → latest。is not switching between managed_import ↔ sync_link
  • Preconditions:sync_mode=pinned_commit
  • Already latest: return ERR_SWITCH_MODE_UNCHANGED
  • Not pinned: return ERR_SWITCH_NOT_ALLOWED
  • Payload:
    • managed_import:_confirm_git_switch_mode({})(passing file_selections will be rejected by the backend)
    • sync_link:_confirm_git_switch_mode({file_selections?})(optional, derived from preview)

Phase 6: Relationship Evolution (supported by both managed_import and sync_link)

This is sync_link'sonlybinding set evolution path under the current phase (managed_import's addFiles is merely an optional means parallel to confirm_git_sync).

Add Files (addFiles)

Files that exist in the repository but do not yet have a binding on Testany:

  1. testany_get_git_add_files_summary — available=false cannot go through; see blocked_reason
  2. testany_list_git_add_files_candidates — get the snapshot_commit and the candidate list
    • Read the complete candidate set, and select only the files/metadata authorized for this round; new candidates do not automatically expand authorization
  3. testany_confirm_git_add_files({selected_files, snapshot_commit}) — idempotency_key Automatically generated by the MCP
    • snapshot_commit Must be passed back verbatim The value obtained during list; if the value does not match, the backend will reject it, preventing a stale candidate set from being persisted under a race condition

Source file deleted (sourceDeleted)

Deleted in the repository but with the binding still present on Testany: the same summary → list → confirm flow, but the confirm parameter is file_binding_ids(not file_path). The impact of deletion/decommissioning must be within the permission scope and cannot be derived from script synchronization. Submit according to the snapshot_commit from this round's list, and after submission verify the binding and the actual processing result.


Phase 7: Sync Audit

  • testany_list_git_sync_records({import_history_id, page?, per_page?})
  • testany_get_git_sync_record({record_id, detail_page?, detail_per_page?}) Go through the per-file results

Phase 8:Webhook

Action Tool
View configuration testany_get_git_webhook_config
Enable / change track_scope testany_update_git_webhook_config({webhook_enabled: true, track_scope?})
Disable testany_disable_git_webhook
Rotate secret testany_regenerate_git_webhook_secret

Key discipline:webhook_secret Onlyfirst-time enablementorjust regenerated is plaintext in the response; afterwards reads are all masked. Once plaintext is obtained:

  1. Immediately have the user enter this secret in the Git platform hook configuration
  2. At the same time, hand platform_setup_guide.steps over to the user in full
  3. Have the user trigger a test event and observe webhook_status from pending_verification → verified

Things that must be reminded to the user

  1. OAuth must be completed in a browser: the agent cannot click authorization on the user's behalf; after returning authorize_url , it must clearly inform them and take on the polling status.initiate_git_oauth The frontend_return_uri required(absolute URL), strictly validated by the backend
  2. webhook_secret appears only once: after first-time enablement or regeneration, it must be recorded immediately and synchronized to the Git side; otherwise the only option is to rotate it again
  3. addFiles / sourceDeleted depend on snapshot_commit(both managed_import and sync_link): the value obtained during the list phase is passed back verbatim to confirm
  4. sync_link does not go through this under the current phase confirm_git_sync: the backend returns 422. To evolve the binding set, use addFiles / sourceDeleted
  5. Deleting a connection does not cascade-delete import history: that import history will become not_ready, and reauthorization is required
  6. Gather evidence first, authorize according to impact: sync / switch uses this round's complete preview, relation uses the candidate snapshot; if the existing permission covers the actual difference, do not ask again; for out-of-bounds/deletion/drift, follow the synchronized authorization decision table stop the corresponding submission
  7. Do not make the user choose a workspace unless necessary: the top-level workspace_key is an optional compatibility field, not a required UX item. Ask only when the user explicitly wants to create a restricted case and the per-file workspace_keys is not provided
  8. Do not assume deployment_type: before allowing a global case, use tenantClient.getCreditStatus or confirm the environment type with the user;deployment_type=2 under the environment, global will be directly rejected by the backend (E400001)
  9. Do not interrogate the language when choosing a Runtime: directly list the testany_filter_case_runtimes results for the user to choose from, with the default recommendation being CloudPrime-Default
  10. Do not manually pass idempotency_key: MCP automatically generates UUIDs internally in preview_sync / confirm_sync / retry_sync / confirm_add_files / confirm_source_deleted; passing an old-style UUID only adds an unnecessary step of code at the upper layer. Only pass a valid UUID explicitly when you clearly need deduplication across multiple calls
  11. installation_id must be selected from the connection:connection.installation_bindings[*].installation_id, and the corresponding binding's account_login must match the repo_full_name owner, otherwise 400

Common Questions

User Question Handling
"Why wasn't the new file synced?" testany_get_git_import Check remote_latest_commit vs last_synced_commit; in managed mode also check the addFiles summary
"Can a sync be rolled back?" V2 does not support rollback; the closest option is to use switchCommit to return to the old commit
"Which import created these cases?" testany_list_git_import_file_bindings in test_case_key reverse lookup
"Webhook isn't receiving events" Check webhook_status(pending_verification / error)+ platform_setup_guide
"The connection became not_ready" Read not_ready_reason, use reauthorize or refreshScope to recover

Reference