buildRepositoryPermissions creates the repository permissions map for gh-aw
(repoName, owner string, additionalRepos []string)
| 217 | |
| 218 | // buildRepositoryPermissions creates the repository permissions map for gh-aw |
| 219 | func buildRepositoryPermissions(repoName, owner string, additionalRepos []string) map[string]DevcontainerRepoPermissions { |
| 220 | // Create repository permissions map |
| 221 | // Reference: https://docs.github.com/en/codespaces/managing-your-codespaces/managing-repository-access-for-your-codespaces |
| 222 | // Default codespace permissions are read/write to the repository from which it was created. |
| 223 | // For the current repo, we grant the standard codespace write permissions plus workflows:write |
| 224 | // to enable triggering GitHub Actions workflows. |
| 225 | // Note: Repository permissions can only be set for repositories in the same organization. |
| 226 | repositories := map[string]DevcontainerRepoPermissions{ |
| 227 | repoName: { |
| 228 | Permissions: map[string]string{ |
| 229 | "actions": "write", |
| 230 | "checks": "write", |
| 231 | "contents": "write", |
| 232 | "discussions": "read", |
| 233 | "issues": "read", |
| 234 | "pull-requests": "write", |
| 235 | "workflows": "write", |
| 236 | }, |
| 237 | }, |
| 238 | } |
| 239 | |
| 240 | // Add additional repositories with read permissions |
| 241 | // For additional repos, we grant default codespace read permissions plus workflows:read |
| 242 | // to allow reading workflow definitions without write access. |
| 243 | // Since permissions must be in the same organization, we automatically prepend the owner. |
| 244 | // Reference: https://docs.github.com/en/codespaces/managing-your-codespaces/managing-repository-access-for-your-codespaces#setting-additional-repository-permissions |
| 245 | for _, repo := range additionalRepos { |
| 246 | if repo == "" { |
| 247 | continue |
| 248 | } |
| 249 | |
| 250 | // If repo already contains '/', validate that the owner matches |
| 251 | // Otherwise, prepend the owner |
| 252 | fullRepoName := repo |
| 253 | if strings.Contains(repo, "/") { |
| 254 | // Validate that the owner matches the current repo's owner |
| 255 | parts := strings.Split(repo, "/") |
| 256 | if len(parts) >= 2 { |
| 257 | repoOwner := parts[0] |
| 258 | if owner != "" && repoOwner != owner { |
| 259 | // Skip repos with different owners rather than error |
| 260 | devcontainerLog.Printf("Skipping repository '%s' - different owner than current repo (expected: '%s')", repo, owner) |
| 261 | continue |
| 262 | } |
| 263 | } |
| 264 | } else if owner != "" { |
| 265 | fullRepoName = owner + "/" + repo |
| 266 | } |
| 267 | |
| 268 | if fullRepoName != repoName { |
| 269 | repositories[fullRepoName] = DevcontainerRepoPermissions{ |
| 270 | Permissions: map[string]string{ |
| 271 | "actions": "read", |
| 272 | "contents": "read", |
| 273 | "discussions": "read", |
| 274 | "issues": "read", |
| 275 | "pull-requests": "read", |
| 276 | "workflows": "read", |
no test coverage detected