MFB-Technologies-Inc / azure-devops-swift

MIT License
0 stars 0 forks source link

Typing for the "Status" policy type configuration #2

Open sam-mfb opened 2 months ago

sam-mfb commented 2 months ago

The typing for the Status policy type configuration (policy id "cbdc66da-9728-4af8-aada-9a5a32e4a226") is (sorry, in Typescript):

export type AdoStatusPolicySettings = {
  /** Status genre, e.g., "SonarCloud" */
  statusGenre: string
  /** Status name **/
  statusName: string
  /**
   * Identity that can post this status. `null` indicates
   * any identity can post this status
   * */
  authorId: string | null
  /**
   * Reset status whenever there are changes to the source code
   */
  invalidateOnSourceUpdate: boolean
  /**
   * Display name for the status. `null` uses an Azure-selected
   * default
   */
  defaultDisplayName: string | null
  /**
   * null: Apply by default
   * 1: The policy is applied only after a status is posted to
   * the pull request
   */
  policyApplicability: null | 1
  /**
   * If a path filter is set, the policy will only apply when
   * files which match the filter are changed. Leaving this field
   * undefined means that the policy will always apply.
   *
   * You can specify absolute paths (path must start either by "/"
   * or a wildcard) and wildcards.
   *
   * Example: /WebApp/Models/Data.cs, /WebApp/*, or *.cs
   *
   * You can specify multiple paths using ";" as a separator.
   *
   * Example: /WebApp/Models/Data.cs;/ClientApp/Models/Data.cs
   *
   * Paths prefixed with "!" are excluded if they would otherwise
   * be included.
   * Example: /WebApp/*;!/WebApp/Tests/*
   *
   * Order is significant. Filters are applied left to right.
   */
  filenamePatterns?: string[]
  scope: AdoPolicyScope[]
}

export type AdoPolicyScope = {
  // e.g., 'refs/heads/develop'
  refName: string
  matchKind: "Exact" | string
  // null seems to mean any repo
  repositoryId: string | null
}

Their appear to be some status's that switch the semantic meaning of statusGenre and statusName (e.g., the codecoverage status seems to always put codecoverage in the name and the project name as the genre)

It is possible to query a list of recent status checks of type

export type AdoStatusCheck = {
  genre: string
  name: string
}

By using the undocumented endpoint https://dev.azure.com/[YOUR_ORG]/_apis/Contribution/HierarchyQuery?api-version==5.0-preview.1 with a POST body as follows:

      {
        contributionIds: ["ms.vss-code-web.branch-policies-data-provider"],
        dataProviderContext: {
          properties: {
            projectId: "YOUR_PROJECTS_GUID",
            refName: "", //this can also be an actual branch like refs/heads/my_branch
            repositoryId: "YOUR_REPOS_GUID"
          }
        }
      }

This will return the following object:

/**
 * Type returned when querying the HierarchyQuery endpoint for the
 * ms.vss-code-web.branch-policies-data-provider provider
 */
export type BranchPolicyDataProviderResponse = {
  dataProviderSharedData: Record<string, unknown> | null
  dataProviders: {
    "ms.vss-web.component-data": Record<string, unknown> | null
    "ms.vss-web.shared-data": Record<string, unknown> | null
    "ms.vss-code-web.branch-policies-data-provider": AdoBranchPoliciesDataProvider
  }
}

export type AdoBranchPoliciesDataProvider = {
  identities: Identity[]
  supportServicePrincipals: boolean
  isEditable: boolean
  policyGroups: Record<string, AdoPolicyGroup>
  buildDefinitions: Record<
    string,
    {
      id: number
      name: string
      path: string
      createdDate: string
      definitionQuality: number
      hasQueueBuildPermission: boolean
    }
  > | null
  recentStatuses: AdoStatusCheck[]
}

export type AdoStatusCheck = {
  genre: string
  name: string
}

export type AdoPolicyGroup = {
  currentScopePolicies: AdoPolicy[]
  enterpriseManagedPolicies: AdoPolicy[]
  inheritedPolicies: AdoPolicy[]
}

export type Identity = {
  id: string
  uniqueName: string
  displayName: string
  url: string
  _links: {
    avatar: Link
  }
  imageUrl: string
  descriptor: string
}

 * Minimum information about a branch policy type */
export type AdoPolicyTypeMin = {
  id: string
  url: string
  displayName: string
}

/** Object representing a policy that is applied to a particular branch */
export type AdoPolicy = {
  id: number
  type: AdoPolicyTypeMin
  /** settings, whose type varies depending on the policy type */
  settings: Record<string, unknown>
  createdBy: Identity
  createdDate: string
  isEnabled: boolean
  isBlocking: boolean
  isDeleted: boolean
  isEnterpriseManaged: boolean
  revision: number
  url: string
  _links: {
    self: Link
    policyType: Link
  }
}

export type Link = { href: string }

The recentStatus object is what you want...

sam-mfb commented 2 months ago

On POST requests to the MS api for creating status policies, no validation is done for what you put in statusGenre and statusName. So if you have some other way of determining what those will be (including what they will be in the future once they start posting), you can add that to the policy at creation time and it will go through. That is, the policy will be created--but it won't pass until the status starts reporting.

In other words, you don't HAVE to check to recent statuses to see what's there, though that may be a nice convenience.