import { type components } from '@octokit/openapi-types'; import { expectType } from 'ts-data-forge'; import * as t from 'ts-fortress'; import { type DeepReadonly } from 'ts-type-forge'; const RepositoryRuleCreation = t.record({ type: t.literal('creation'), }); expectType< t.TypeOf, DeepReadonly >('='); const RepositoryRuleUpdate = t.record({ type: t.literal('update'), parameters: t.optional( t.record({ /** @description Branch can pull changes from its upstream repository */ update_allows_fetch_and_merge: t.boolean(), }), ), }); expectType< t.TypeOf, DeepReadonly >('='); const RepositoryRuleDeletion = t.record({ type: t.literal('deletion'), }); expectType< t.TypeOf, DeepReadonly >('='); const RepositoryRuleRequiredLinearHistory = t.record({ type: t.literal('required_linear_history'), }); expectType< t.TypeOf, DeepReadonly >('='); const RepositoryRuleMergeQueue = t.record({ type: t.literal('merge_queue'), parameters: t.optional( t.record({ /** @description Maximum time for a required status check to report a conclusion. After this much time has elapsed, checks that have not reported a conclusion will be assumed to have failed */ check_response_timeout_minutes: t.number(), /** * @description When set to ALLGREEN, the merge commit created by merge queue for each PR in the group must pass all required checks to merge. When set to HEADGREEN, only the commit at the head of the merge group, i.e. the commit containing changes from all of the PRs in the group, must pass its required checks to merge. * @enum {string} */ grouping_strategy: t.enumType(['ALLGREEN', 'HEADGREEN']), /** @description Limit the number of queued pull requests requesting checks and workflow runs at the same time. */ max_entries_to_build: t.number(), /** @description The maximum number of PRs that will be merged together in a group. */ max_entries_to_merge: t.number(), /** * @description Method to use when merging changes from queued pull requests. * @enum {string} */ merge_method: t.enumType(['MERGE', 'SQUASH', 'REBASE']), /** @description The minimum number of PRs that will be merged together in a group. */ min_entries_to_merge: t.number(), /** @description The time merge queue should wait after the first PR is added to the queue for the minimum group size to be met. After this time has elapsed, the minimum group size will be ignored and a smaller group will be merged. */ min_entries_to_merge_wait_minutes: t.number(), }), ), }); expectType< t.TypeOf, DeepReadonly >('='); const RepositoryRuleRequiredDeployments = t.record({ type: t.literal('required_deployments'), parameters: t.optional( t.record({ /** @description The environments that must be successfully deployed to before branches can be merged. */ required_deployment_environments: t.array(t.string()), }), ), }); expectType< t.TypeOf, DeepReadonly >('='); const RepositoryRuleRequiredSignatures = t.record({ type: t.literal('required_signatures'), }); expectType< t.TypeOf, DeepReadonly >('='); const RepositoryRuleParamsReviewer = t.record({ /** @description ID of the reviewer which must review changes to matching files. */ id: t.number(), /** * @description The type of the reviewer * @enum {string} */ type: t.literal('Team'), }); expectType< t.TypeOf, DeepReadonly >('='); const RepositoryRuleParamsRequiredReviewerConfiguration = t.record({ /** @description Array of file patterns. Pull requests which change matching files must be approved by the specified team. File patterns use fnmatch syntax. */ file_patterns: t.array(t.string()), /** @description Minimum number of approvals required from the specified team. If set to zero, the team will be added to the pull request but approval is optional. */ minimum_approvals: t.number(), reviewer: RepositoryRuleParamsReviewer, }); expectType< t.TypeOf, DeepReadonly< components['schemas']['repository-rule-params-required-reviewer-configuration'] > >('='); const RepositoryRulePullRequest = t.record({ type: t.literal('pull_request'), parameters: t.optional( t.record({ /** @description Array of allowed merge methods. Allowed values include `merge`, `squash`, and `rebase`. At least one option must be enabled. */ allowed_merge_methods: t.optional( t.array(t.enumType(['merge', 'squash', 'rebase'])), ), /** @description New, reviewable commits pushed will dismiss previous pull request review approvals. */ dismiss_stale_reviews_on_push: t.boolean(), /** @description Require an approving review in pull requests that modify files that have a designated code owner. */ require_code_owner_review: t.boolean(), /** @description Whether the most recent reviewable push must be approved by someone other than the person who pushed it. */ require_last_push_approval: t.boolean(), /** @description The number of approving reviews that are required before a pull request can be merged. */ required_approving_review_count: t.number(), /** @description All conversations on code must be resolved before a pull request can be merged. */ required_review_thread_resolution: t.boolean(), /** * @description > [!NOTE] * > `required_reviewers` is in beta and subject to change. * * A collection of reviewers and associated file patterns. Each reviewer has a list of file patterns which determine the files that reviewer is required to review. */ required_reviewers: t.optional( t.array(RepositoryRuleParamsRequiredReviewerConfiguration), ), }), ), }); expectType< t.TypeOf, DeepReadonly >('='); const RepositoryRuleRequiredStatusChecks = t.record({ type: t.literal('required_status_checks'), parameters: t.optional( t.record({ /** @description Allow repositories and branches to be created if a check would otherwise prohibit it. */ do_not_enforce_on_create: t.optional(t.boolean()), /** @description Status checks that are required. */ required_status_checks: t.array( t.record({ /** @description The status check context name that must be present on the commit. */ context: t.string(), /** @description The optional integration ID that this status check must originate from. */ integration_id: t.optional(t.number()), }), ), /** @description Whether pull requests targeting a matching branch must be tested with the latest code. This setting will not take effect unless at least one status check is enabled. */ strict_required_status_checks_policy: t.boolean(), }), ), }); expectType< t.TypeOf, DeepReadonly >('='); const RepositoryRuleNonFastForward = t.record({ type: t.literal('non_fast_forward'), }); expectType< t.TypeOf, DeepReadonly >('='); const CommonPatternParameters = t.record({ /** @description How this rule will appear to users. */ name: t.optional(t.string()), /** @description If true, the rule will fail if the pattern matches. */ negate: t.optional(t.boolean()), /** * @description The operator to use for matching. * @enum {string} */ operator: t.enumType(['starts_with', 'ends_with', 'contains', 'regex']), /** @description The pattern to match with. */ pattern: t.string(), }); const RepositoryRuleCommitMessagePattern = t.record({ type: t.literal('commit_message_pattern'), parameters: t.optional(CommonPatternParameters), }); expectType< t.TypeOf, DeepReadonly >('='); const RepositoryRuleCommitAuthorEmailPattern = t.record({ type: t.literal('commit_author_email_pattern'), parameters: t.optional(CommonPatternParameters), }); expectType< t.TypeOf, DeepReadonly< components['schemas']['repository-rule-commit-author-email-pattern'] > >('='); const RepositoryRuleCommitterEmailPattern = t.record({ type: t.literal('committer_email_pattern'), parameters: t.optional(CommonPatternParameters), }); expectType< t.TypeOf, DeepReadonly >('='); const RepositoryRuleBranchNamePattern = t.record({ type: t.literal('branch_name_pattern'), parameters: t.optional(CommonPatternParameters), }); expectType< t.TypeOf, DeepReadonly >('='); const RepositoryRuleTagNamePattern = t.record({ type: t.literal('tag_name_pattern'), parameters: t.optional(CommonPatternParameters), }); expectType< t.TypeOf, DeepReadonly >('='); const RepositoryRuleFilePathRestriction = t.record({ type: t.literal('file_path_restriction'), parameters: t.optional( t.record({ /** @description The file paths that are restricted from being pushed to the commit graph. */ restricted_file_paths: t.array(t.string()), }), ), }); expectType< t.TypeOf, DeepReadonly >('='); const RepositoryRuleMaxFilePathLength = t.record({ type: t.literal('max_file_path_length'), parameters: t.optional( t.record({ /** @description The maximum amount of characters allowed in file paths. */ max_file_path_length: t.number(), }), ), }); expectType< t.TypeOf, DeepReadonly >('='); const RepositoryRuleFileExtensionRestriction = t.record({ type: t.literal('file_extension_restriction'), parameters: t.optional( t.record({ /** @description The file extensions that are restricted from being pushed to the commit graph. */ restricted_file_extensions: t.array(t.string()), }), ), }); expectType< t.TypeOf, DeepReadonly< components['schemas']['repository-rule-file-extension-restriction'] > >('='); const RepositoryRuleMaxFileSize = t.record({ type: t.literal('max_file_size'), parameters: t.optional( t.record({ /** @description The maximum file size allowed in megabytes. This limit does not apply to Git Large File Storage (Git LFS). */ max_file_size: t.number(), }), ), }); expectType< t.TypeOf, DeepReadonly >('='); const WorkflowFileReference = t.record({ /** @description The path to the workflow file */ path: t.string(), /** @description The ref (branch or tag) of the workflow file to use */ ref: t.optional(t.string()), /** @description The ID of the repository where the workflow is defined */ repository_id: t.number(), /** @description The commit SHA of the workflow file to use */ sha: t.optional(t.string()), }); const RepositoryRuleWorkflows = t.record({ type: t.literal('workflows'), parameters: t.optional( t.record({ /** @description Allow repositories and branches to be created if a check would otherwise prohibit it. */ do_not_enforce_on_create: t.optional(t.boolean()), /** @description Workflows that must pass for this rule to pass. */ workflows: t.array(WorkflowFileReference), }), ), }); expectType< t.TypeOf, DeepReadonly >('='); const CodeScanningTool = t.record({ /** * @description The severity level at which code scanning results that raise alerts block a reference update. * @enum {string} */ alerts_threshold: t.enumType([ 'none', 'errors', 'errors_and_warnings', 'all', ]), /** * @description The severity level at which code scanning results that raise security alerts block a reference update. * @enum {string} */ security_alerts_threshold: t.enumType([ 'none', 'critical', 'high_or_higher', 'medium_or_higher', 'all', ]), /** @description The name of a code scanning tool */ tool: t.string(), }); const RepositoryRuleCodeScanning = t.record({ type: t.literal('code_scanning'), parameters: t.optional( t.record({ /** @description Tools that must provide code scanning results for this rule to pass. */ code_scanning_tools: t.array(CodeScanningTool), }), ), }); expectType< t.TypeOf, DeepReadonly >('='); const RepositoryRuleCopilotCodeReview = t.record({ type: t.literal('copilot_code_review'), parameters: t.optional( t.partial( t.record({ review_on_push: t.boolean(), review_draft_pull_requests: t.boolean(), }), ), ), }); export const RepositoryRule = t.union([ RepositoryRuleCreation, RepositoryRuleUpdate, RepositoryRuleDeletion, RepositoryRuleRequiredLinearHistory, RepositoryRuleMergeQueue, RepositoryRuleRequiredDeployments, RepositoryRuleRequiredSignatures, RepositoryRulePullRequest, RepositoryRuleRequiredStatusChecks, RepositoryRuleNonFastForward, RepositoryRuleCommitMessagePattern, RepositoryRuleCommitAuthorEmailPattern, RepositoryRuleCommitterEmailPattern, RepositoryRuleBranchNamePattern, RepositoryRuleTagNamePattern, RepositoryRuleFilePathRestriction, RepositoryRuleMaxFilePathLength, RepositoryRuleFileExtensionRestriction, RepositoryRuleMaxFileSize, RepositoryRuleWorkflows, RepositoryRuleCodeScanning, RepositoryRuleCopilotCodeReview, ]); expectType< t.TypeOf, DeepReadonly >('~=');