> For the complete documentation index, see [llms.txt](https://wiki.nushackers.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.nushackers.org/hackerschool/ci-cd-with-github-actions/advanced-use-cases/github-script.md).

# Github script

You might also want to interact with the Github API during your workflows. Some of the common use cases we've noticed include:

1. Fetching information about the repository/pull request/user
2. Creating issues
3. Creating issue/pull request comments
4. Updating issues/pull requests
5. Retrieving information about another repository
6. Automatically running jobs and creating commit

You can use the Github API via Github script, an action that allows you to write Javascript scripts using the Github API — `actions/github-script@v7`.

{% @github-files/github-code-block url="<https://github.com/actions/github-script>" %}

The `README.md` of the action contains a lot of examples of use cases with the Github script. However, we will just cover a very simple script to illustrate a few points:

```yaml
on:
  issues:
    types: [opened]

jobs:
  comment:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: '👋 Thanks for reporting!'
            })
```

In the above example, we are using Github script to create a new comment on a newly created issue. We can see that the event that triggers this workflow is the `issues`  event, when one is `opened`.&#x20;

The various API calls are based on the Octokit documentation: <https://octokit.github.io/rest.js/v21/> where you replace `octokit` with `github` !

You might be wondering, "How does the Github script have access to the Github API when some APIs require an API token?"

Amazing question! This is where the `GITHUB_TOKEN` we talked about in [Deploying to Github Pages](/hackerschool/ci-cd-with-github-actions/basics-of-github-actions/deploying-to-github-pages.md#permissions-and-secrets) come into play. By default, Github script uses the `GITHUB_TOKEN` to access these APIs, which means that it is restricted to only accessing the current repository. Therefore, if you wish to access other repositories or data that does not belong to the current repository and requires authentication, you will need to:

1. Create a Personal Access Token: <https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic>
2. Add it to the repository's secrets: <https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions>
3. Set the `github-token` input for the action: see below

```yaml
on:
  issues:
    types: [opened]

jobs:
  apply-label:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v7
        with:
          github-token: ${{ secrets.MY_PAT }}
          script: |
            github.rest.issues.addLabels({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              labels: ['Triage']
            })
```

Another thing you can use Github script for is combining it with [Pollers](/hackerschool/ci-cd-with-github-actions/advanced-use-cases/pollers.md) to automatically perform some actions to the current repository at set intervals. An example of this might be to poll for new information across multiple repositories and updating a set of files on the current repository as commits:

```yaml
on:
  workflow_dispatch:
  schedule:
    - cron: "0 12 * * *"
jobs:
  poll:
    runs-on: ubuntu-latest
    steps:
      - name: Fetch all
        uses: actions/github-script@v7
        with:
          github-token: ${{ secrets.ORG_PAT }}
          script: |
            const repos = await github.paginate(github.rest.search.repos, {
              q: "<query string>",
            })

            let newReadme = `
            <updating the README>
            `
            const existingReadme = await github.rest.repos.getContent({
              owner: context.repo.owner,
              repo: "<repo>",
              path: "README.md",
            })

            await github.rest.repos.createOrUpdateFileContents({
              owner: context.repo.owner,
              repo: "<repo>",
              path: "README.md",
              message: "Update README",
              content: btoa(newReadme),
              sha: existingReadme.data.sha,
            })
```

This poller runs every day at midnight UTC, fetching all repositories that satisfy some query string and updating the README of the current repository as a commit.
