I need to check out a private repo during a GitHub Actions workflow. I am using the checkout action, and following its README:
I created a service account, i.e. a separate GitHub account just for GitHub Actions workflow.
I created a PAT (Personal Access Token) for the service account, with permission to access the private repo and the current workflow repo.
I created a secret to store the PAT token.
Now, when I just do the following, it does not work:
- name: Checkout
uses: actions/checkout#v2
with:
token: ${{secrets.MY_TOKEN}}
it seems that I did not config git properly to allow it use the token. My question is: should I or how do I configure git config to use token in the above step?
The private repo is a dependency of the main repo. Both repos are Rust programs, using Cargo, so I am trying to use the same service account to check out the main repo first. Then cargo will check out the private repo.
According to the actions/checkout documentation, you need to add the repository input as well for private repositories:
It should look like the following on your workflow .yml file:
- name: Checkout
uses: actions/checkout#v2
with:
path: main
- name: Checkout private repo
uses: actions/checkout#v2
with:
repository: your-private/repo_name
token: ${{ secrets.MY_TOKEN }}
You shouldn't need to configure anything else regarding git
Except if you need a specific path, in that case you need to inform it as input as well:
- name: Checkout private repo
uses: actions/checkout#v2
with:
repository: your-private/repo_name
token: ${{ secrets.MY_TOKEN }}
path: path-to-directory
Related
I'm currently testing Github Actions workflows on this repository.
Context
I'm trying to use this workflow (1st):
on:
workflow_dispatch:
jobs:
job:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- run: |
date > report.txt
git config user.name github-actions
git config user.email github-actions#github.com
git add .
git commit -m "generate or update report.txt file"
git push
To trigger this workflow (2nd):
on:
push:
paths:
- '**/report.txt'
pull_request:
paths:
- '**/report.txt'
jobs:
job:
runs-on: ubuntu-latest
steps:
- run: echo "Report .txt file has been updated"
What I tried
I followed the Github Action Documentation to implement the 2nd workflow with a Filter Pattern.
When I update the report.txt file locally, then commit and push the code to the repository, the 2nd workflow triggers.
However, I don't understand why the 2nd workflow doesn't trigger when the 1st workflow is completed, even with the report.txt file being updated on the default branch.
EDIT: I know I could trigger the 2nd workflow using others trigger event types (examples: repository_dispatch or workflow_run). But I'm trying to do it from a git push command on another workflow.
Question
Did I miss something on the 1st workflow to make it trigger the 2nd, or should I add something on the 2nd workflow to make it being triggered by the 1st one?
No, you didn't miss anything in your workflows.
You just need a different token.
When you use actions/checkout, it uses the GITHUB_TOKEN for authentication, and according to the documentation it doesn't trigger a new workflow run:
When you use the repository's GITHUB_TOKEN to perform tasks on behalf
of the GitHub Actions app, events triggered by the GITHUB_TOKEN will
not create a new workflow run. This prevents you from accidentally
creating recursive workflow runs.
To make it work, you need to generate a PAT (Personal Access Token), store it in your repository secrets, and use it in your checkout step:
- uses: actions/checkout#v2
with:
token: ${{ secrets.YOUR_PAT_TOKEN }}
There are three ways of authentication within a GitHub action.
1. GITHUB_TOKEN
The GITHUB_TOKEN is always available and implicitly defined by GitHub.
- uses: actions/checkout#v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
It has limited permissions, though, as it cannot trigger new workflow runs. This is why your second workflow does not start.
2. PAT (Personal Access Token)
A personal access token can be generated in your developer settings. You can then add it as an encryped secret, e.g. PAT_TOKEN to the GitHub project and use it instead of the GITHUB_TOKEN:
- uses: actions/checkout#v3
with:
token: ${{ secrets.PAT_TOKEN }}
Subsequent push actions in the same workflow will then trigger any configured GitHub workflow as if they were pushed manually.
Be aware that the personal access token has access to all of your repositories and hence can be a potential security risk.
3. Deploy key
You can generate a dedicated SSH keypair and add it to the repository as a Deploy Key. This is an alternative to the token-based authentication and has the same effect as the personal access token, but it only provides access to a single repository. It is done as follows:
Generate an SSH keypair:
ssh-keygen -N "" -f deploy_key -C "github-actions"
Add the private key (generated file deploy_key) as an encryped secret, e.g. COMMIT_KEY to the GitHub project.
Add the public key (generated file deploy_key.pub) as a deploy key with write access to the GitHub project. Tick the Allow write access checkbox.
When checking out the source code in your workflow, add the SSH key:
- uses: actions/checkout#v3
with:
ssh-key: "${{secrets.COMMIT_KEY}}"
I have a GitHub action that I have created in order to create a new version and publish it for our JS repo. It looks similar to this
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout#v2
- uses: actions/setup-node#v1
with:
node-version: 12.18.3
registry-url: https://npm.pkg.github.com/
scope: '<redacted>'
- name: Install Dependencies
run: npm ci
- name: Build
run: npm run build
- name: Bump Version & Push
run: |
git config --local user.email "<redacted>"
git config --local user.name "<redacted>"
npm version patch
git push https://${{ secrets.KEY }}#github.com/<redacted> HEAD:master --follow-tags
The KEY that I am using is a person access token I created from my account. I have set the repo so that I have push access to the master branch. When I try the push command from my machine with the access token it works without an issue. However every time I see this in the GitHub Action
remote: error: GH006: Protected branch update failed for refs/heads/master.
remote: error: You're not authorized to push to this branch. Visit https://docs.github.com/articles/about-protected-branches/ for more information.
I have been racking my brain trying to figure this out and I'm out to ideas. If I remove the branch protection this action works fine.
I think this is because of how authentication is persisted by actions/checkout. It's stored in an extraheader config option which takes precedence over the credentials you are setting manually.
Try not persisting the auth:
- uses: actions/checkout#v2
with:
persist-credentials: false
Or alternatively:
- uses: actions/checkout#v2
with:
token: ${{ secrets.KEY }}
I know this because I've had my own issue with overriding this config option in the past.
I want to automate the build and publishing of the docs of an open source typescript project hosted on Github.
I tried TypeDoc and the generated docs folder is 23Mo. I don't want to commit it in the project's repo.
Ideally, on each release, I would like to use github actions to:
generate the docs
push that generated docs folder to its own github repo.
Currently I added a npm script to generate the docs: docs: typedoc --out docs src and here is the starting point of my github action file:
name: Docs
on:
release:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout#v1
- name: Use Node.js
uses: actions/setup-node#v1
with:
node-version: 12
- name: Generate docs
run: |
npm ci
npm run docs
From this action, how can I commit and push this generated directory to its own repo on github?
(Maybe there is a more conventional way to do that. Let me know)
If you want to commit and push changes, you can refer to some actions in the Github's marketplace like github-push or push changes to see if they are fitting your situation. Also, you can write your own script to call Github's API, e.g. I use Pygithub to call Github's APT to help me generate changelog and update the file in the repo.
You can use the github-action-push-to-another-repository action for this purpose:
- name: Pushes to another repository
uses: cpina/github-action-push-to-another-repository#main
env:
API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }}
with:
source-directory: <directory-where-the-dist-is-generated>
destination-github-username: <github-username>
destination-repository-name: <github-repository-name>
user-email: <github-email>
target-branch: <main/master>
I'm trying to work out how to use Github Actions to checkout a remote public repo, then add some some sensitive files into it from the current repo, before finally building etc.
I believe I can checkout a remote repo with
steps:
- name: Checkout
uses: actions/checkout#v2
with:
repository: foo-user/bar-repo
But how do I then copy some files into this checked out repo from files that are in the current repo?
You have a couple options:
Checkout your repo and then checkout the public repo:
steps:
- uses: actions/checkout#v2
- name: Checkout
uses: actions/checkout#v2
with:
repository: foo-user/bar-repo
path: './bar'
Now you can go ahead and copy files from the folder bar into whereever else you want
The other option is to have the public repo as a submodule, then you can simply do:
steps:
- name: Checkout
uses: actions/checkout#v2
with:
submodules: true
Can I trigger a new workflow from another workflow?
I'm trying to run a workflow after the first workflow has pushed a new release and it seems to ignore it.
Found the answer here:
An action in a workflow run can't trigger a new workflow run. For example, if an action pushes code using the repository's GITHUB_TOKEN, a new workflow will not run even when the repository contains a workflow configured to run when push events occur.
EDIT:
The quote above might be confusing. When I add a Personal Access Token (PAT) to the checkout action with repo permissions granted (and not repository's GITHUB_TOKEN), the following commands DO trigger other workflows:
- name: Checkout Repo
uses: actions/checkout#v2
with:
token: ${{ secrets.PAT_TOKEN }}
(In my case, running semnatic-release after this checkout, which creates a new release with a new tag - did trigger another workflow that runs only if a tag was created)
As described here, you can trigger another workflow using the workflow_run event.
For example we could think of two workflow definitions like this (the only prerequisite is, that both reside in the same repository - but I'am sure, there's also an event for other repos as well):
release.yml
name: CI release
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: Release artifact
run: ...
do-something-different.yml
name: Do anything after the release of the first workflow
on:
workflow_run:
workflows: ["CI release"]
types:
- completed
jobs:
notify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: Do something
run: ...
A crucial point here is that the name: CI release definition of the first yaml file must exactly match the workflow_run: workflows: ["CI release"] definition in the second yaml file. Another point is that this approach needs to be done on the default branch (which is mostly main or master) as the docs state:
Note: This event will only trigger a workflow run if the workflow file
is on the default branch.
If you don't want to use a general Personal Access Token (which has access to all of your repos), you can generate a dedicated SSH keypair for this purpose and add it to the repository as a Deploy Key. This is done as follows:
Generate an SSH keypair:
ssh-keygen -N "" -f deploy_key -C "github-actions"
Add the private key (generated file deploy_key) as an encryped secret, e.g. COMMIT_KEY to the GitHub project.
Add the public key (generated file deploy_key.pub) as a deploy key with write access to the GitHub project. Tick the Allow write access checkbox.
When checking out the source code in your workflow, add the SSH key:
- name: Checkout
uses: actions/checkout#v3
with:
ssh-key: "${{secrets.COMMIT_KEY}}"
Subsequent push actions in the same workflow will then trigger any configured GitHub workflow as if they were pushed manually.