diff --git a/.github/workflows/setup-new-repo.yml b/.github/workflows/setup-new-repo.yml
index 45856dd..4266942 100644
--- a/.github/workflows/setup-new-repo.yml
+++ b/.github/workflows/setup-new-repo.yml
@@ -1,4 +1,18 @@
# .github/workflows/setup-new-repo.yml
+#
+# Prerequisites:
+# - A GitHub environment named `repo-setup` must exist.
+# - The environment must contain a secret `GH_REPO_CREATE_TOKEN`.
+# - This token must be a fine-grained personal access token (FGPAT) with the following:
+# β’ Repository access: Allow access to the template repo and target org repos.
+# β’ Permissions:
+# - Contents: Read and write
+# - Issues: Read and write
+# - Metadata: Read-only
+# - Administration: Read and write (for repo settings, team setup)
+#
+# See: https://github.com/settings/tokens for generating tokens
+#
name: Setup New Repository
on:
@@ -38,24 +52,39 @@ jobs:
- name: Checkout template repository
uses: actions/checkout@v4
- - name: Set up GitHub CLI token with personal access token
+ - name: Set up GitHub CLI token with personal fine grained access token
run: |
+ # Use GH_REPO_CREATE_TOKEN as the authentication token for all GitHub CLI commands
echo "GH_TOKEN=${{ secrets.GH_REPO_CREATE_TOKEN }}" >> $GITHUB_ENV
- echo "Token GH_REPO_CREATE_TOKEN ready for use in GitHub CLI"
+ if [ -z "${{ secrets.GH_REPO_CREATE_TOKEN }}" ]; then
+ echo "::error::GH_REPO_CREATE_TOKEN is not set. Please configure the secret in the 'repo-setup' environment."
+ exit 1
+ fi
- name: Create new repository and set variables
run: |
REPO_NAME=${{ github.event.inputs.repo_name }}
+ # Extract the owner (user or organization) part of the current repository (before the slash)
OWNER=$(echo '${{ github.repository }}' | cut -d'/' -f1)
- echo "Checking if repository $OWNER/$REPO_NAME already exists..."
- if gh api repos/$OWNER/$REPO_NAME > /dev/null 2>&1; then
- echo "::error::Repository $OWNER/$REPO_NAME already exists. Exiting."
- exit 1
- fi
-
echo "Creating new repository: https://github.com/$OWNER/$REPO_NAME"
- gh repo create "$OWNER/$REPO_NAME" --public --template "$OWNER/$(basename '${{ github.repository }}')" --confirm
+ # Creates a new public repository using the current repository as a template
+ gh repo create "$OWNER/$REPO_NAME" --public --template "$OWNER/$(basename '${{ github.repository }}')"
+
+ # Wait until the repository is fully accessible
+ for i in {1..5}; do
+ if gh api repos/$OWNER/$REPO_NAME > /dev/null 2>&1; then
+ echo "::notice::Repository $OWNER/$REPO_NAME is now available."
+ break
+ else
+ echo "Waiting for repository $OWNER/$REPO_NAME to become available..."
+ sleep 4
+ fi
+ done
+
+ if ! gh api repos/$OWNER/$REPO_NAME > /dev/null 2>&1; then
+ echo "::warning::Repository $OWNER/$REPO_NAME did not become available after 5 attempts. Continuing anyway."
+ fi
echo "REPO_NAME=$REPO_NAME" >> $GITHUB_ENV
echo "OWNER=$OWNER" >> $GITHUB_ENV
@@ -67,6 +96,7 @@ jobs:
run: |
if gh api orgs/$OWNER/teams > /dev/null 2>&1; then
if ! gh api orgs/$OWNER/teams/$MAINTAINERS_TEAM > /dev/null 2>&1; then
+ # Retrieve the numeric ID of the 'maintainers' team to use as the parent_team_id
MAINTAINERS_PARENT_ID=$(gh api orgs/$OWNER/teams/maintainers | jq -r '.id')
MAINTAINERS_PARENT_ID_NUM=$(echo "$MAINTAINERS_PARENT_ID" | grep -o '[0-9]*')
echo "Debug: MAINTAINERS_PARENT_ID_NUM=$MAINTAINERS_PARENT_ID_NUM"
@@ -101,6 +131,10 @@ jobs:
fi
CODEOWNERS_LIST=$(echo "$CODEOWNERS_LIST" | xargs)
+ # Loop through each provided GitHub username and invite them to the codeowners team
+ # Note: users who are not yet members of the organization will be invited to join
+ # and will need to accept the invitation before they are part of the team and the CODEOWNERS file get fully valid
+ echo "Inviting users to team $CODEOWNERS_TEAM: [$CODEOWNERS_LIST]"
for username in $CODEOWNERS_LIST; do
clean_user=$(echo "$username" | sed 's/^@//')
echo "Checking if @$clean_user is a valid GitHub user..."
@@ -118,7 +152,7 @@ jobs:
- name: Configure repository settings
run: |
gh repo edit $OWNER/$REPO_NAME \
- --description "$REPO_NAME" \
+ --description "Sandbox API Repository for $REPO_NAME API(s)" \
--homepage "${{ github.event.inputs.repo_wiki_page }}" \
--add-topic sandbox-api-repository
gh api -X PATCH repos/$OWNER/$REPO_NAME \
@@ -128,7 +162,8 @@ jobs:
- name: Update README.md placeholders
run: |
- # changes the README.md from template repository and updates the README.md in the new repository with it
+ # Replace placeholders in the template README.md and push the updated version to the new repository
+ # Note: the README.md file is expected to be in the root of the repository
sed -i "s/{{repo_name}}/$REPO_NAME/g" README.md
sed -i "s|{{repo_wiki_page}}|${{ github.event.inputs.repo_wiki_page }}|g" README.md
sed -i "s|{{subproject_name}}|${{ github.event.inputs.subproject_name }}|g" README.md
@@ -136,6 +171,7 @@ jobs:
sed -i "s|{{mailinglist_name}}|${{ github.event.inputs.mailinglist_name }}|g" README.md
sed -i "s|{{initial_codeowners}}|${{ github.event.inputs.initial_codeowners }}|g" README.md
+ # Retry loop: waits for README.md to appear in the new repo (max 5 attempts)
SHA=""
for i in {1..5}; do
SHA=$(gh api repos/$OWNER/$REPO_NAME/contents/README.md 2>/dev/null | jq -r '.sha')
@@ -185,7 +221,10 @@ jobs:
- name: Update CODEOWNERS file
run: |
- sed "s|{{initial_codeowners}}|$CODEOWNERS_LIST|g" templates/CODEOWNERS > CODEOWNERS
+ # Replace placeholder in CODEOWNERS template with actual list of codeowners
+ # Note: also users who are skipped during team invitation will be added to the CODEOWNERS file and
+ # might need to be corrected manually later and invited manually to the CODEOWNERS team
+ sed "s|{{initial_codeowners}}|$CODEOWNERS_LIST|g" templates/CODEOWNERS_TEMPLATE > CODEOWNERS
CODEOWNERS_SHA=$(gh api repos/$OWNER/$REPO_NAME/contents/CODEOWNERS | jq -r '.sha')
gh api repos/$OWNER/$REPO_NAME/contents/CODEOWNERS \
@@ -200,6 +239,7 @@ jobs:
TEMPLATE_REPO=$(basename "${{ github.repository }}")
echo "Fetching rulesets from $OWNER/$TEMPLATE_REPO"
+ # Fetch all rulesets defined in the template repository for later replication
RULESETS=$(gh api repos/$OWNER/$TEMPLATE_REPO/rulesets \
-H "Accept: application/vnd.github+json" 2>/dev/null || echo "[]")
@@ -236,3 +276,25 @@ jobs:
gh issue comment "$ADMIN_ISSUE_URL" \
--body "β
Repository setup has been completed by automation. You may now proceed with the checklist."
+ - name: Cleanup setup artifacts from template repository
+ run: |
+ # Explicit list of files to remove after setup (e.g., templates and placeholders)
+ FILES_TO_DELETE=(
+ "templates/CODEOWNERS"
+ "templates/issues/initial-admin.md"
+ "templates/issues/initial-codeowners.md"
+ "templates/README.md"
+ )
+
+ for file in "${FILES_TO_DELETE[@]}"; do
+ if gh api repos/$OWNER/$REPO_NAME/contents/$file > /dev/null 2>&1; then
+ sha=$(gh api repos/$OWNER/$REPO_NAME/contents/$file | jq -r '.sha')
+ gh api repos/$OWNER/$REPO_NAME/contents/$file \
+ -X DELETE \
+ -F message="Remove $file from template repository" \
+ -F sha="$sha" || echo "::error::Failed to delete $file"
+ echo "::notice::Deleted $file"
+ else
+ echo "::warning::File $file not found during cleanup. Skipping."
+ fi
+ done
diff --git a/CODEOWNERS b/CODEOWNERS
index 9449381..4739da7 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -1,4 +1,6 @@
-# This file provides an overview of code owners in this repository.
+# This file provides an overview of code owners in this repository
+
+# Note: this is the actual CODEOWNERS file to protect the template repository. The CODEONWERS file in newly created repositories will be build based on /templates/CODEOWNERS_TEMPLATE
# Each line is a file pattern followed by one or more owners.
# The last matching pattern has the most precedence.
diff --git a/README.md b/README.md
index 73f6e70..8898022 100644
--- a/README.md
+++ b/README.md
@@ -5,42 +5,45 @@
-
+
# {{repo_name}}
> [!NOTE]
-> What is this repository about and how to use it:
+> What is this template repository about and how to use it:
>
-> * For codeowners of existing CAMARA repository as a sample how a CAMARA repository should look like, e.g. to update legacy repositories. Have a look specifically on the [code of the README.md](https://github.com/camaraproject/Template_API_Repository/blob/main/README.md?plain=1) for different variants and copy relevant parts into your repository.
+> * For codeowners of existing CAMARA repository it is a sample how a CAMARA repository should look like, e.g. to update legacy repositories. Have a look specifically on the [code of the README.md](https://github.com/camaraproject/Template_API_Repository/blob/main/README.md?plain=1) for different variants and copy relevant parts into your repository.
> * For CAMARA admins to create new (Sandbox) API repositories automated: Use the `setup-new-repo` workflow together with documentation in [templates/README.md](templates/README.md).
>
-> The following is the template README for a new independent Sandbox API repository, other variants are within the commented code.
+> The following is the template README for a new independent Sandbox repositories, Sandbox repositories within a Sub Project, and Incubated Repositories. Further variants are within the commented code.
+>
+> This note must be deleted in newly created repositories
+
+---
+
-
+
Sandbox API Repository to describe, develop, document, and test the {{repo_name}} Service API(s). The repository does not yet belong to a CAMARA Sub Project.
* API Repository [wiki page]({{repo_wiki_page}})
-
+---
+
-
-
+---
+
-
@@ -49,7 +52,7 @@ Incubating API Repository to evolve and maintain the definitions and documentati
Repository for xxx of the {{subproject_name}} Working Group"
* Working Group [wiki home page]({{repo_wiki_page}})
-!! Update with concrete link
+
-->
## Scope
diff --git a/templates/CODEOWNERS b/templates/CODEOWNERS_TEMPLATE
similarity index 100%
rename from templates/CODEOWNERS
rename to templates/CODEOWNERS_TEMPLATE
diff --git a/templates/README.md b/templates/README.md
index dbf836f..26e8d03 100644
--- a/templates/README.md
+++ b/templates/README.md
@@ -1,110 +1,138 @@
-# π Sandbox API Repository Creation Automation for CAMARA
+# π Automation for CAMARA API Repository Creation
-This document describes how to use the GitHub Action in the `Template_API_Repository` to automate the setup of new API repositories within the CAMARA GitHub organization or within a personal namespace.
+The automation workflow "Setup New Repository" simplifies the process of setting up a new CAMARA API repository, ensuring consistency across teams and reducing manual steps.
+
+This document describes how to use the GitHub Action in the `Template_API_Repository` to automate the setup of new API repositories within the [CAMARA GitHub organization](https://github.com/camaraproject).
---
## π Purpose
-To automate the initial setup of a new repository, including:
+To automate the initial administrative setup of a new API repository, ensuring consistency and reducing manual work. This includes:
-- Creating a new repository from the template
-- Setting metadata and repository settings
-- Creating teams and assigning permissions (if in an organization)
-- Adding CODEOWNERS based on a template
-- Posting issues with initial checklists
-- Cleaning up setup artifacts (workflow + templates) - not yet implemented
+- Creating a new public repository based on the template
+- Setting repo description, topics, and metadata
+- Creating and configuring teams
+- Assigning repository permissions
+- Updating the README with project-specific details
+- Adding CODEOWNERS
+- Creating initial administrative issues
+- Cleaning up template files from the new repository
---
## βοΈ How to Use
-1. Go to the **Actions** tab of your fork or the template repo
-2. Trigger the **"Setup New Repository"** workflow manually using **workflow\_dispatch**
-3. Fill in the following inputs:
-
-### π’ Inputs
-
-- `repo_name`: Name of the new repository to create
-- `subproject_name`: Optional subproject/working group name
-- `repo_wiki_page`: Link to the repository wiki
-- `subproject_wiki_page`: Optional link to the subproject wiki
-- `mailinglist_name`: Mailing list for project discussion
-- `initial_codeowners`: Space-separated GitHub usernames with `@` (e.g., `@alice @bob`)
+### π Prerequisites for Administrators
----
+Before running the workflow, ensure the following are set up:
-## π What It Does
+1. **Environment Setup**:
-### β
Repository
+ - A GitHub environment named `repo-setup` must exist in the template repository.
-- Creates a new public repository from the template
-- Sets description, homepage (to wiki), and topic `sandbox-api-repository`
-- Enables issues and discussions, disables wiki
+2. **Fine-Grained Personal Access Token (FGPAT)**:
-### β
Teams
+ - A secret named `GH_REPO_CREATE_TOKEN` must be stored in the `repo-setup` environment.
+ - This token must be a **fine-grained personal access token** with access to both the template and target repositories.
-- Creates `repo_name_maintainers` and `repo_name_codeowners` under parent teams (if applicable)
-- Adds each codeowner to the CODEOWNERS team (if user exists)
+ #### π Required Token Permissions:
-### β
Files
+ - **Contents**: Read and write
+ - **Issues**: Read and write
+ - **Metadata**: Read-only
+ - **Administration**: Read and write
-- Replaces placeholders in `README.md`
-- Generates CODEOWNERS from `templates/CODEOWNERS`
-- Posts 2 issues using templates in `templates/issues/*.md`
-- Adds a comment to the first issue confirming setup success
+ #### π§ How to Create a Fine-Grained Token:
-### β
Rulesets
+ 1. Go to [GitHub Developer Settings β Fine-grained personal access tokens](https://github.com/settings/personal-access-tokens)
+ 2. Click **"Generate new token (fine-grained)"**
+ 3. Set **Resource owner** to your GitHub username (for testing) or organization (camaraproject)
+ 4. Choose **repositories to access**: all repositories (otherwise newly created repositories are not covered)
+ 5. Under **Repository permissions**, set:
+ - Contents β Read and write
+ - Issues β Read and write
+ - Metadata β Read-only
+ - Administration β Read and write
+ - Generate the token and copy it
+ 6. Add it as the `GH_REPO_CREATE_TOKEN` secret under **Settings > Environments > repo-setup**
-- Sync rulesets from template repository
+---
-### β
Cleanup (currently not implemented)
+### βΆοΈ Running the Workflow
-- Deletes the workflow file itself from the new repo
-- Deletes all files inside the `templates/` folder
+1. Go to the `Actions` tab of [`Template_API_Repository`](https://github.com/camaraproject/Template_API_Repository/actions)
+2. Select the **"Setup New Repository"** workflow
+3. Use the `workflow_dispatch` form to input the following values:
----
+#### π€ Inputs
-## π Requirements
+| Input | Required | Description |
+| ---------------------- | -------- | ------------------------------------------------------------------------------------------------------------ |
+| `repo_name` | β
| Name of the new repository to create |
+| `subproject_name` | β | Optional subproject or working group name |
+| `repo_wiki_page` | β
| URL of the new repository's wiki page |
+| `subproject_wiki_page` | β | URL of the subprojectβs wiki page (if applicable) |
+| `mailinglist_name` | β
| Mailing list associated with the repo |
+| `initial_codeowners` | β
| Space-separated GitHub usernames (with `@`). Ensure each user exists and can be invited to the organization. |
-### π GitHub Personal Access Token (PAT)
+#### π‘ Example Input:
-- Stored as repository or environment secret: `GH_REPO_CREATE_TOKEN`
-- Must have scopes:
- - `repo`
- - `admin:org` (if using teams)
+```text
+repo_name: my-new-api
+subproject_name: mobility
+repo_wiki_page: https://github.com/camaraproject/my-new-api/wiki
+subproject_wiki_page: https://github.com/camaraproject/mobility/wiki
+mailinglist_name: mobility@lists.camaraproject.org
+initial_codeowners: @alice @bob @charlie
+```
-### π‘ Environment Restrictions
+---
-- The workflow is restricted to run in a GitHub Environment: `repo-setup`
-- That environment must be configured in **Settings β Environments**
-- Add the `@camaraproject/admins` team as required reviewers to control access
-- Store the `GH_REPO_CREATE_TOKEN` secret inside this environment
+## π§± What the Workflow Does
+
+This GitHub Actions workflow is defined in the `Template_API_Repository`, which serves as the starting point for all new API repositories in the CAMARA project.
+
+- Creates a new public repository using this template
+- Waits until the repo is accessible
+- Sets metadata:
+ - Description, homepage URL, topic `sandbox-api-repository`
+ - Enables discussions and issues; disables wiki
+- Creates two teams:
+ - `repo_name_maintainers` (under `maintainers`)
+ - `repo_name_codeowners` (under `codeowners`)
+- Assigns permissions:
+ - `triage` to maintainers
+ - `push` to codeowners
+ - `maintain` to admins
+- Updates `README.md` using placeholder replacement
+- Generates and commits a `CODEOWNERS` file from template
+- Syncs all rulesets from the template repository
+- Opens two issues:
+ - Initial administrative tasks
+ - Initial tasks for codeowners
+- Deletes listed template files from the new repository
---
-## π¦ Required Template Files
-
-The following must exist in the `Template_API_Repository`:
+## β
What to Do After the Workflow
-```
-templates/CODEOWNERS
-templates/issues/initial-admin.md
-templates/issues/initial-codeowners.md
-```
+- Follow the instructions and checklist in the created issue "New Repository - Initial administrative tasks #1", especially:
+ - Review the newly created repository and ensure all README placeholders and metadata have been populated correctly
+ - Confirm that the CODEOWNERS file includes valid GitHub usernames. If users are not part of the organization, team invitations may not succeed
+ - Delete `.github/workflows/setup-new-repo.yml` manually from the new repository, as it is not removed automatically
+ - Note: Improvements of this checklist should go into `/templates/issues/initial-admin.md`
---
-## π§ͺ Testing Tips
+## π Future Enhancements
-- Use a test repo name like `test-repo-$(date +%s)` to avoid naming collisions
-- Run in a personal account if you want to skip org/team features
-- Check your repo afterwards for:
- - Metadata
- - CODEOWNERS file
- - Issue templates and comment
- - Removed setup files
+- Set the correct labels for issues and pull requests within the new repository
+- Adding linting workflow (based on reusable workflow from `Tooling`Β repository)
+- Validate usernames/org membership during CODEOWNERS setup
+- Dry-run support for validation without creation
+- Move the workflow out of the template repository into e.g. `.github` or `Tooling` repository (requires some rewriting of the workflow)
---
-For questions, open an issue in the template repository or contact a CAMARA admin.
+For questions or feedback, open an issue in [`Template_API_Repository`](https://github.com/camaraproject/Template_API_Repository/issues) or reach out via the mailing list [adm@lists.camaraproject.org](mailto\:adm@lists.camaraproject.org).
diff --git a/templates/issues/initial-admin.md b/templates/issues/initial-admin.md
index f9def62..f4a2ba2 100644
--- a/templates/issues/initial-admin.md
+++ b/templates/issues/initial-admin.md
@@ -1,11 +1,11 @@
## Initial Administrative Tasks
-- [ ] Review repository settings
-- [ ] Check that the CODEOWNERS file is valid (initial codeowners have accepted the invitation)
-- [ ] Remove the content of /templates and the /.github/workflows/setup-new-repo.yml
+- [ ] Review repository settings, see [documentation of workflow](https://github.com/camaraproject/Template_API_Repository/tree/main/templates).
+- [ ] Check that the CODEOWNERS file is valid (potential need to wait until initial codeowners have accepted the invitation)
+- [ ] Remove /.github/workflows/setup-new-repo.yml in the new repository (as long as it is copied into it)
- [ ] Update the README
- choose the right badge (default: Sandbox)
- - choose the right variant of text for Independent Sandbox / Sandbox in Sub Project / ...
+ - choose the right variant for Independent Sandboxes,Sandboxes in Sub Project, Incubating, or repository for working group
- check the wiki links for correctness
- [ ] Assign the initial issue for CODEWONERS to the appropriate codeowners
- [ ] Update the Onboarding Tracker within APIBacklog