Code Repositories, Branches and Projects
A code repository is a repository linked to GitHub, with all its branches;
the SDK model is CodeRepository. A branch, CodeRepositoryBranch, is one
Git branch of a repository in one Organization Environment, with the Jobs,
releases and Agent that run from it. A Project, OrganizationProject, is a
named group of branches in one Environment, whose policies pass down to them. A
Project groups branches; it is not a repository.
Who can use each of them is decided by its policies. This page says what each policy allows; Who Has Access to an Object describes the access methods and their models. Organization admins hold every action on all three.
Who can use a code repository
A code repository's access is decided by its policies:
reader: see the repository, its GitHub link and issues, and every branch in it;editor: also rename or archive it, add deploy keys, create branches, edit every branch, and see who has access;owner: also decide who has access.
The repository's creator holds owner. Deleting a repository is in no policy:
only Organization admins delete one, so explain_access("code-repositories.delete")
names no policy that gives it. A deploy key lets a machine push to the GitHub
repository, which is part of what editor gives.
A repository's policies pass down to every branch: reader gives reader on
each branch, and editor and owner give editor. A branch lives in an
Environment, so a person reaches it only in an Environment they work in.
A policy on one of the repository's branches, held directly, through a Team or
through a Project, also reaches the repository without reaching its other
branches. Branch reader gives the computed policy branch_reader: the
repository appears in lists and search, with its GitHub link, branch names and
issues. Branch editor and owner give branch_editor, which also adds deploy
keys, so a person who edits a branch can develop locally. get_access() shows
them as computed rows with source inherited that name the branch. Neither
can be attached, and both apply only while the person works in the branch's
Environment.
The policies go only to people with the platform's user product role, to
workload identities and to Teams; a Light User does not have that role. Using a
repository needs the role too: a person without it gets
PermissionDeniedError with code missing_product_role from every
repository route, the access routes included, also when a Team they belong to
holds a policy. That refusal names no policy, because no policy can give it.
Read and change the policies with the access methods on CodeRepository:
from mainsequence.client import CodeRepository
repository = CodeRepository.get_by_uid(code_repository_uid)
for binding in repository.get_access().bindings:
print(binding.uid, binding.policy.id, binding.principal.type, binding.principal.uid)
binding = repository.attach_policy("reader", principal_type="team", principal_uid=team_uid)
repository.detach_policy(binding.uid)
answer = repository.explain_access("code-repositories.update", principal_uid=user_uid)
print(answer.allowed, answer.granting_policies)
The access methods address the repository by its UID alone and take no
Environment. They need a person's session: the platform refuses them to a
workload's runtime credentials. A refused change raises
PermissionDeniedError, whose payload names the required_action and the
granting_policies. mainsequence access policies --type code-repositories
lists the policies with their actions.
Who can use a branch
A branch's access is decided by its policies:
reader: see the branch, its files and issues, and its Jobs, runs, logs and releases, and call its releases, whose logs can contain request data; it also finds and shows the branch's repository;editor: also change and delete the branch, create issues and static sites, edit its Jobs and releases, manage what its workloads can reach, add deploy keys to its repository, and see who has access;owner: also decide who has access.
Creating a branch gives its creator nothing on it. A branch also takes the
policies held above it: reader on its repository, or on a Project it belongs
to, gives reader on the branch, and editor or owner there gives editor.
get_access() shows each of those as a computed row with source
inherited, which names the holder, the parent and the parent's policy. The
branch's policies pass down in turn to its releases and its standalone Jobs:
reader gives viewer there, and editor and owner give editor. Up to
the repository they give branch_reader or branch_editor
(Who can use a code repository), never its
other branches. A release that backs the branch's Agent follows the Agent
instead; see
Who can use a release and
Who can use a Job.
Deleting a branch deletes its releases, its Agent, its Jobs and its build
contexts. Deleting a repository's last branch deletes the repository, so it
also needs the repository's delete action, which only Organization admins
hold.
The policies go to people, workload identities and Teams. A person without the
platform's user product role gets PermissionDeniedError with code
missing_product_role from every branch route, the access routes included,
also when a Team they belong to holds a policy. A repository workflow file's
access.branch and access.branches entries give the declaring workload the
policy they name on the branch (branch: reader, or policy: reader on a
branches entry).
from mainsequence.client import CodeRepositoryBranch
branch = CodeRepositoryBranch.get_by_uid(branch_uid)
for row in branch.get_access().computed:
print(row.source, row.policy, row.parent_policy)
branch.attach_policy("editor", principal_type="user", principal_uid=workload_user_uid)
print(branch.get_my_access().allowed_actions)
The access methods address the branch by its UID alone and take no
Environment, and the platform refuses them to runtime credentials.
mainsequence access policies --type code-repository-branches lists the
policies with their actions.
Who can use a Project
A Project's access is decided by its policies:
reader: see the Project, every branch in it, and those branches' repositories;editor: also rename it, add and remove branches, delete it, add deploy keys to its branches' repositories, and see who has access;owner: also decide who has access.
The Project's creator holds owner. A Project's policies pass down to its
branches: reader gives reader on each of them, and editor and owner
give editor. Through each branch they reach its repository as
branch_reader or branch_editor, so a Project editor finds the repositories
and adds deploy keys to develop locally, without reaching their other
branches. Adding a branch to a Project also needs editor or owner on
that branch, and deleting a Project keeps its branches. The policies go to
people, workload identities and Teams.
The SDK has no other Project methods: OrganizationProject carries only the
Project's UID, which is all its access methods use.
from mainsequence.client import OrganizationProject
project = OrganizationProject(uid=project_uid)
binding = project.attach_policy("reader", principal_type="team", principal_uid=team_uid)
print([item.policy.id for item in project.get_access().bindings])
The access methods take no Environment, and the platform refuses them to
runtime credentials. mainsequence access policies --type organization-projects
lists the policies with their actions.
From the command line
These commands read and change a code repository's policies:
mainsequence code-repository access list <CODE_REPOSITORY_UID>
mainsequence code-repository access grant <CODE_REPOSITORY_UID> reader --user <USER_UID>
mainsequence code-repository access grant <CODE_REPOSITORY_UID> editor --team <TEAM_UID>
mainsequence code-repository access revoke <CODE_REPOSITORY_UID> <BINDING_UID>
mainsequence code-repository access explain <CODE_REPOSITORY_UID> code-repositories.update
<USER_UID> is the public UUID of the person or workload identity receiving
the policy, <TEAM_UID> the team's, and <BINDING_UID> the UID of a binding,
which access list shows. The commands address the repository by its UID
alone and need no registered branch. A refused command prints the platform's
message and the policies that would allow it; a missing product role prints
the platform's message. The CLI has no commands for branches and Projects: use
their access methods. See
Code repositories in the CLI reference.