From a2d77658d6bebb847f6042107435f49e06af2963 Mon Sep 17 00:00:00 2001 From: Shakar Bakr <5h4k4r.b4kr@gmail.com> Date: Thu, 5 Jun 2025 11:18:59 +0300 Subject: [PATCH] Refactor action.yml to use composite runs and enhance README for private repository support - Updated action.yml to switch from Docker to composite runs, allowing for improved token generation for private repositories. - Added new inputs for GitHub App authentication: APP_ID, PRIVATE_KEY, and OWNER. - Enhanced README with detailed instructions for using the action with private repositories, including GitHub App setup and authentication methods. Signed-off-by: Alastair Mooney Signed-off-by: Shakar Bakr <5h4k4r.b4kr@gmail.com> --- README.md | 63 ++++++++++++++++++++++++++----- action.yml | 107 +++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 129 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index f808921..6dcf5a7 100644 --- a/README.md +++ b/README.md @@ -60,16 +60,59 @@ def hello_world(): The action supports creating issues in a different repository than the one where the TODO comments are found. This requires: 1. Setting the `TARGET_REPO` input to specify the target repository (e.g., "owner/repo") -2. Providing a token with write access to the target repository via the `TOKEN` input -```yaml -- uses: alstr/todo-to-issue-action@v5 - with: - TARGET_REPO: "my-org/target-repo" - TOKEN: ${{ secrets.CROSS_REPO_TOKEN }} -``` +2. Providing appropriate authentication: + - For public repositories or when the target repository is in the same organization, use the default `GITHUB_TOKEN`: + ```yaml + - uses: alstr/todo-to-issue-action@v5 + with: + TARGET_REPO: "my-org/target-repo" + ``` + - For private repositories, provide GitHub App credentials: + ```yaml + - uses: alstr/todo-to-issue-action@v5 + with: + TARGET_REPO: "target-org/target-repo" + APP_ID: ${{ secrets.APP_ID }} + PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }} + OWNER: "target-org" + ``` -Note: When using a custom token for cross-repository access, it must be properly scoped with permissions to create issues in the target repository. +The action will automatically: +1. Use the default `GITHUB_TOKEN` for same-repo or public repository access +2. Generate a GitHub App token when `APP_ID` and `PRIVATE_KEY` are provided for private repository access + +### GitHub App Setup + +To use the action with private repositories, you'll need to: + +1. Create a GitHub App: + - Go to your GitHub account settings + - Navigate to "Developer settings" (bottom of the left sidebar) + - Click "GitHub Apps" and then "New GitHub App" + - Fill in the following details: + - **GitHub App name**: Choose a unique name (e.g., "TODO-to-Issue-App") + - **Homepage URL**: Your repository URL + - **Webhook**: Leave disabled + - **Repository permissions**: + - Issues: Read & Write + - Pull requests: Read & Write (if using PR integration) + - **Where can this GitHub App be installed?**: Any account + - Click "Create GitHub App" + - On the next page, click "Generate a private key" to download your private key file + - Note down the "App ID" shown on the page + +2. Store the following secrets in your repository: + - Go to your repository's "Settings" → "Secrets and variables" → "Actions" + - Add two new repository secrets: + - `APP_ID`: The App ID you noted down + - `PRIVATE_KEY`: The entire contents of the private key file you downloaded (including the BEGIN and END lines) + +3. Install the GitHub App: + - Go back to your GitHub App settings + - Click "Install App" in the left sidebar + - Choose the target repository where you want to create issues + - Click "Install" As per the [Google Style Guide](https://google.github.io/styleguide/cppguide.html#TODO_Comments), you can provide a _reference_ after the TODO identifier: @@ -305,7 +348,7 @@ using the `LANGUAGES` input. Just create a file that contains an array of languages, each with the following properties: | Property | Description | -|------------|----------------------------------------------------------------------------------------------------------------------------------------------------| +| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | language | The unique name of the language | | extensions | A list of file extensions for the custom language | | markers | A list of objects (see example below) to declare the comment markers. Make sure to escape all special Markdown characters with a double backslash. | @@ -551,6 +594,6 @@ Thanks to all those who have [contributed](https://github.com/alstr/todo-to-issu ## Supporting the Project -If you’ve found this action helpful and it has made your workflow easier, please consider buying a coffee to help keep it going. Thank you in advance! +If you've found this action helpful and it has made your workflow easier, please consider buying a coffee to help keep it going. Thank you in advance! [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/alstr18858) diff --git a/action.yml b/action.yml index f9c8e2f..445cf6e 100644 --- a/action.yml +++ b/action.yml @@ -1,91 +1,136 @@ -name: 'TODO to Issue' -description: 'Converts IDE TODO comments to GitHub issues' -author: 'Alastair Mooney' +name: "TODO to Issue" +description: "Converts IDE TODO comments to GitHub issues" +author: "Alastair Mooney" runs: - using: 'docker' - image: 'docker://ghcr.io/alstr/todo-to-issue-action:v5.1.12' + using: "composite" + steps: + - name: Generate token for private repository access + if: ${{ inputs.TARGET_REPO != '' && inputs.APP_ID != '' }} + id: generate-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ inputs.APP_ID }} + private-key: ${{ inputs.PRIVATE_KEY }} + owner: ${{ inputs.OWNER }} + repositories: ${{ inputs.TARGET_REPO }} + shell: bash + + - name: Run TODO to Issue action + uses: docker://ghcr.io/alstr/todo-to-issue-action:v5.1.12 + with: + REPO: ${{ inputs.REPO }} + BEFORE: ${{ inputs.BEFORE }} + COMMITS: ${{ inputs.COMMITS }} + DIFF_URL: ${{ inputs.DIFF_URL }} + SHA: ${{ inputs.SHA }} + TOKEN: ${{ inputs.APP_ID != '' && steps.generate-token.outputs.token || inputs.TOKEN }} + TARGET_REPO: ${{ inputs.TARGET_REPO }} + CLOSE_ISSUES: ${{ inputs.CLOSE_ISSUES }} + AUTO_P: ${{ inputs.AUTO_P }} + PROJECT: ${{ inputs.PROJECT }} + PROJECTS_SECRET: ${{ inputs.PROJECTS_SECRET }} + IGNORE: ${{ inputs.IGNORE }} + AUTO_ASSIGN: ${{ inputs.AUTO_ASSIGN }} + ACTOR: ${{ inputs.ACTOR }} + ISSUE_TEMPLATE: ${{ inputs.ISSUE_TEMPLATE }} + IDENTIFIERS: ${{ inputs.IDENTIFIERS }} + GITHUB_URL: ${{ inputs.GITHUB_URL }} + GITHUB_SERVER_URL: ${{ inputs.GITHUB_SERVER_URL }} + ESCAPE: ${{ inputs.ESCAPE }} + LANGUAGES: ${{ inputs.LANGUAGES }} + NO_STANDARD: ${{ inputs.NO_STANDARD }} + INSERT_ISSUE_URLS: ${{ inputs.INSERT_ISSUE_URLS }} branding: - icon: 'check-square' - color: 'orange' + icon: "check-square" + color: "orange" inputs: REPO: description: "The path to the repository where the action will be used, e.g. 'alstr/my-repo' (automatically set)" required: false - default: '${{ github.repository }}' + default: "${{ github.repository }}" BEFORE: - description: 'The SHA of the last pushed commit (automatically set)' + description: "The SHA of the last pushed commit (automatically set)" required: false - default: '${{ github.event.before || github.base_ref }}' + default: "${{ github.event.before || github.base_ref }}" COMMITS: - description: 'An array of commit objects describing the pushed commits (automatically set)' + description: "An array of commit objects describing the pushed commits (automatically set)" required: false - default: '${{ toJSON(github.event.commits) }}' + default: "${{ toJSON(github.event.commits) }}" DIFF_URL: - description: 'The URL to use to get the diff (automatically set)' + description: "The URL to use to get the diff (automatically set)" required: false - default: '${{ github.event.pull_request.diff_url }}' + default: "${{ github.event.pull_request.diff_url }}" SHA: - description: 'The SHA of the latest commit (automatically set)' + description: "The SHA of the latest commit (automatically set)" required: false - default: '${{ github.sha }}' + default: "${{ github.sha }}" TOKEN: - description: 'The GitHub access token to allow us to retrieve, create and update issues (automatically set)' + description: "The GitHub access token to allow us to retrieve, create and update issues (automatically set)" required: false default: ${{ github.token }} TARGET_REPO: description: "Optional target repository to create issues in (e.g. 'owner/repo'). If not provided, issues will be created in the current repository." required: false + APP_ID: + description: "GitHub App ID for generating tokens to access private repositories" + required: false + PRIVATE_KEY: + description: "Private key for the GitHub App (do not enter the actual secret)" + required: false + OWNER: + description: "Owner of the target repository (required if using GitHub App authentication)" + required: false CLOSE_ISSUES: - description: 'Optional input specifying whether to attempt to close an issue when a TODO is removed' + description: "Optional input specifying whether to attempt to close an issue when a TODO is removed" required: false default: true AUTO_P: - description: 'For multiline TODOs, format each line as a new paragraph when creating the issue' + description: "For multiline TODOs, format each line as a new paragraph when creating the issue" required: false default: true PROJECT: description: "User or organization project to link issues to, format 'project_type/owner/project_name'" required: false PROJECTS_SECRET: - description: 'Encrypted secret corresponding to your personal access token (do not enter the actual secret)' + description: "Encrypted secret corresponding to your personal access token (do not enter the actual secret)" required: false IGNORE: - description: 'A collection of comma-delimited regular expression that matches files that should be ignored when searching for TODOs' + description: "A collection of comma-delimited regular expression that matches files that should be ignored when searching for TODOs" required: false AUTO_ASSIGN: - description: 'Automatically assign new issues to the user who triggered the action' + description: "Automatically assign new issues to the user who triggered the action" required: false default: false ACTOR: - description: 'The username of the person who triggered the action (automatically set)' + description: "The username of the person who triggered the action (automatically set)" required: false - default: '${{ github.actor }}' + default: "${{ github.actor }}" ISSUE_TEMPLATE: - description: 'The template used to format new issues' + description: "The template used to format new issues" required: false IDENTIFIERS: - description: 'Dictionary of custom identifiers' + description: "Dictionary of custom identifiers" required: false GITHUB_URL: - description: 'Base url of GitHub API' + description: "Base url of GitHub API" required: false default: ${{ github.api_url }} GITHUB_SERVER_URL: - description: 'Base URL of GitHub web interface' + description: "Base URL of GitHub web interface" required: false default: ${{ github.server_url }} ESCAPE: - description: 'Escape all special Markdown characters' + description: "Escape all special Markdown characters" required: false default: true LANGUAGES: - description: 'A collection of comma-delimited URLs or local paths for custom language files' + description: "A collection of comma-delimited URLs or local paths for custom language files" required: false NO_STANDARD: description: "Exclude loading the default 'syntax.json' and 'languages.yml' files from the repository" required: false default: false INSERT_ISSUE_URLS: - description: 'Whether the action should insert the URL for a newly-created issue into the associated TODO comment' + description: "Whether the action should insert the URL for a newly-created issue into the associated TODO comment" required: false default: false