GitHub Integration
By default, many projects are initialized with GitHub component to enabled GitHub as the default provider for CI/CD workflows. See https://docs.github.com/en/actions for more information.
The use of GitHub (and generating corresponding files in .github) can be disabled by specifying github: false in your project options.
GitHub API access
Several workflows generated by projen use APIs that are not available through the permissions of GITHUB_TOKEN. To use these workflows, you must provide either a Personal Access Token (PAT) or a GitHub App to provide API access.
Personal Access Token (classic)
Follow the GitHub docs
instructions
for creating a personal access token (classic).
When creating the classic PAT, grant the token repo, workflow and write:packages permissions.
Add the token as a secret to your repo under the name PROJEN_GITHUB_TOKEN.
Fine-grained Personal Access Token (beta)
Follow the GitHub docs instructions for creating a fine-grained personal access token (beta).
Select the repositories you want to use this token for. You can reuse the same token for multiple repositories if you select them here. However you should choose the minimal repository access that meets your needs.
Under Permissions, select the following Repository Permissions:
Contents- Read and writeMetadata- Read-only (automatically added)Pull requests- Read and writeWorkflows- Read and write
Add the token as a secret to your repo under the name PROJEN_GITHUB_TOKEN.
GitHub App
Follow the GitHub docs instructions for creating a GitHub App. Enable read & write permission for "Contents" and "Pull Request" scopes.
Add the App ID as a secret to your repo under the name PROJEN_APP_ID and generate a private key for the app to store as a secret to your repo under the name PROJEN_APP_PRIVATE_KEY.
Install the application ensuring that the repo(s) that you wish to grant access to are selected.
Then, configure your projenrc file to use the GitHub app for API access:
const { github, javascript } = require('projen');
const project = new javascript.NodeProject({
// ...other options
githubOptions: {
projenCredentials: github.GithubCredentials.fromApp({ ... }),
},
});
If the GitHub app you are using has additional permissions assigned, you can limit the permissions used on the token within the jobs in the workflow to only allow access to write repository contents and create the pull request:
const { github, javascript } = require('projen');
const project = new javascript.NodeProject({
// ...other options
githubOptions: {
projenCredentials: github.GithubCredentials.fromApp({
// ...other options
permissions: {
pullRequests: github.workflows.AppPermission.WRITE,
contents: github.workflows.AppPermission.WRITE,
}
}),
},
});
Workflows
See the GitHub, GithubWorkflow, and Job types in the GitHub and GitHub Workflow API references for currently available APIs.
Example code of creating a GitHub workflow: https://github.com/projen/projen/blob/65b4194c163f47ba4842981b0c92dbe516be787b/src/github/auto-approve.ts#L67-L105
Step IDs
When jobs are added or updated (via addJobs / updateJobs), projen automatically
assigns a stable, deterministic id to every step that doesn't already have one.
This makes steps referenceable by other steps and jobs — for example through needs,
conditional expressions (if: steps.<id>.outputs.*), and output consumption — without
requiring you to annotate every step manually.
IDs are assigned using the following priority:
- Explicit
id— if a step already defines anid, it is preserved as-is and is never renamed (it may already be referenced elsewhere). - Derived from
name— the stepnameis converted tosnake_case, keeping only characters valid in a GitHub workflow id (for example"Install dependencies"becomesinstall_dependencies). - Content hash fallback — for steps with neither an
idnor aname, anauto_prefix plus an 8-character SHA-256 hash of the step'srunorusescontent is used (for exampleauto_65b1296e).
Duplicate explicit IDs within the same job throw an error. Derived or auto-generated IDs
that would collide with an explicit id (or with each other) are disambiguated with a
_2, _3, … suffix.
IDs are assigned eagerly at addJobs / updateJobs time rather than during render. This
guarantees that any id appearing in the rendered YAML is also reachable through the
step-mutation API (getStep, patchStep, replaceStep, appendStep, removeStep,
insertStepBefore, insertStepAfter).
!!! note
Steps injected from job.tools (e.g. actions/setup-node, actions/setup-java)
are produced during synthesis and are intentionally left without an auto-generated
id, since they are not addressable through the projen step API.
Actions versions
Most workflows included with projen are constraint to a major version, in order for updates to be available immediately. However it is a good security practice to lock versions of GitHub Actions down to explicit commit hashes. To achieve this, you can define explicit overrides for any action used in workflows.
The replace all occurrences of an action can be overridden, irregardless of the action version:
project.github.actions.set("actions/checkout", "actions/checkout@ac59398");
Any use of actions/checkout is now changed to this:
steps:
- uses: actions/checkout@ac59398
Alternatively, any specific action version can be overridden. This can be useful when a specific version of an action must be used due to incompatible changes. Specific overrides take precedence over overrides without a version.
project.github.actions.set("actions/checkout@v4", "actions/checkout@ac59398");
project.github.actions.set("actions/checkout", "actions/checkout@main");
Different versions of actions/checkout are resolved to different overrides:
steps:
# Was: actions/checkout@v4
- uses: actions/checkout@ac59398
# Was: actions/checkout@v2
- uses: actions/checkout@main
Workflow creators are encouraged to use commit hashes and keep them updated, or major versions. Sensitive workflow actions should always use commit hashes.
Stale workflow
A "stale" workflow can be added which will automatically close issues or pull requests on your GitHub repository after time has passed without the issue seeing any comments or updates. You can enable as shown below:
// or PythonProject, etc.
new typescript.TypeScriptProject({
stale: true,
staleOptions: {
issues: {
closeMessage: "closing pull request",
staleLabel: "I-AM-STALE",
daysBeforeStale: 180,
},
}
})
Check the API reference for a list of all available options.
When enabled, by default issues with no activity with will be marked as stale after 60 days and closed within 7 days, and pull requests with no activity will be marked as stale after 14 days and closed within 2 days.