从 GitHub 操作推送到原点
Push to origin from GitHub action
我正在尝试从 GitHub 操作推送到 origin
远程。我的操作逻辑是:
- 处理
pull_request_review
事件并按评论消息过滤
- checkout 到 master,合并 PR 分支,运行 一些检查并推送到
origin
脚本是:
if [[ "${GITHUB_EVENT_NAME}" != "pull_request_review" ]]; then
echo "unsupported event: ${GITHUB_EVENT_NAME}"
exit 1
fi
user=$(jq -r .review.user.login ${GITHUB_EVENT_PATH})
cmd=$(jq -r .review.body ${GITHUB_EVENT_PATH})
echo "reviewer is ${user}, command is ${cmd}"
if [[ "${cmd}" == "merge" ]]; then
head=$(jq -r .pull_request.head.ref ${GITHUB_EVENT_PATH})
git config user.email test@test.com
git config user.name test
git checkout -B _tmp origin/${head}
git checkout -B master origin/master
git merge --no-ff _tmp
git push origin master
fi
我运行从 alpine:3.10
Docker 容器
中安装此脚本
FROM alpine:3.10
LABEL "com.github.actions.name"="Hello world action"
LABEL "com.github.actions.icon"="shield"
LABEL "com.github.actions.color"="green"
WORKDIR /app
COPY action.sh action.sh
RUN apk --update add bash git jq
CMD ["bash", "/app/action.sh"]
第一步工作正常(签出和合并),但操作未能将合并推送到 origin
,因为错误:
+ git push origin master
fatal: could not read Username for 'https://github.com': No such device or address
看起来 GitHub-action Docker 容器未配置为推送到 GitHub。我该如何配置它?是否可以使用 GitHub 提供的一些 env variables 或者一些挂载的文件(比如 /github/*
路径)?
您可以使用 secrets.GITHUB_TOKEN
作为存储库 URL 的密码。因此,您可以在 git push
行之前添加:
git remote set-url --push origin https://your_username:$GITHUB_TOKEN@github.com/your/repo
这假设您已经将 GITHUB_TOKEN 秘密作为环境变量传递给您的脚本。如果不是,请添加:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
到您的工作流程步骤。
actions/checkout@v2
版本 2 的结帐解决了分离的 HEAD 状态问题并简化了推送到源的过程。
name: Push commit
on: push
jobs:
report:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Create report file
run: date +%s > report.txt
- name: Commit report
run: |
git config --global user.name 'Your Name'
git config --global user.email 'your-username@users.noreply.github.com'
git commit -am "Automated report"
git push
如果您需要推送事件来触发其他工作流程,请使用 repo
作用域 Personal Access Token。
- uses: actions/checkout@v2
with:
token: ${{ secrets.PAT }}
actions/checkout@v1(原答案)
为@rmunn 的出色回答添加更多细节。问题是 actions/checkout@v1
操作使 git 存储库处于分离的 HEAD 状态。有关详细信息,请参阅此问题:https://github.com/actions/checkout/issues/6
这里有一个完整的例子来演示如何将签出的存储库变为可用状态并推送到远程。
name: Push commit
on: push
jobs:
report:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Create report file
run: date +%s > report.txt
- name: Commit report
run: |
git config --global user.name 'Your Name'
git config --global user.email 'your-username@users.noreply.github.com'
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY
git checkout "${GITHUB_REF:11}"
git commit -am "Automated report"
git push
要包含未跟踪的(新)文件,请更改工作流程以使用以下内容。
git add -A
git commit -m "Automated report"
以上工作流程应该适用于大多数活动。对于 on: pull_request
工作流程,应检出合并分支 (GITHUB_HEAD_REF
) 以替换默认的合并提交。
重要提示: 如果除了以下工作流程之外还有其他拉取请求检查,则必须使用 Personal Access Token 而不是默认的 GITHUB_TOKEN
。
这是由于 GitHub 操作故意施加的限制,即工作流引发的事件(例如 push
)无法触发进一步的工作流运行。
这是为了防止意外的“无限循环”情况,并作为一种反滥用措施。
使用 repo
作用域 Personal Access Token 是一种已批准的解决方法。有关解决方法的更多详细信息,请参阅此GitHub问题。
name: Push commit on pull request
on: pull_request
jobs:
report:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
with:
ref: ${{ github.head_ref }}
- name: Create report file
run: date +%s > report.txt
- name: Commit report
run: |
git config --global user.name 'Your Name'
git config --global user.email 'your-username@users.noreply.github.com'
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
git commit -am "Automated report"
git push
有关 on: pull_request
工作流程中推送到源的更多示例,请参阅此博客 post、GitHub Actions: How to Automate Code Formatting in Pull Requests。
所有提供的答案都是正确的。但我想对这些答案再补充一点。可能存在文件没有更改的情况。因此,在那种情况下,当尝试执行 git commit
命令时,它会 returns 导致 GitHub 工作流程失败的错误(失败的工作流程会阻止 PR 合并)。所以在commit之前我们要检查文件是否有变化。
name: Config Generator
on:
pull_request:
branches: [ main ]
jobs:
config-generator:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: ${{ github.head_ref }}
- name: Install jsonnet
run: sudo apt install -y jsonnet
- name: Generate probe configs
run: python3 generate-configs.py
- name: Check for modified files
id: git-check
run: echo ::set-output name=modified::$(if [ -n "$(git status --porcelain)" ]; then echo "true"; else echo "false"; fi)
- name: Update changes in GitHub repository
if: steps.git-check.outputs.modified == 'true'
run: |
git config --global user.name 'Your Name'
git config --global user.email 'Your Email for GitHub'
git add -A
git commit -m '[automated commit] add configs generated using jsonnet & GitHub workflow'
git push
以上工作流程是使用jsonnet和GitHub工作流程创建配置文件的示例。它首先安装 jsonnet 和 运行s 一个 python 脚本,该脚本使用 jsonnet 模板创建配置文件。如上所述,可能存在没有文件更改的情况。所以它使用 git status
命令来检查是否有任何文件更改。 (代替 git status
,也可以使用 git diff
。但它不会显示未跟踪的文件)。其余 git 命令 运行 仅当有文件更改时。
另请注意,即使我使用了 checkout@v2
,我也必须使用 ref: ${{ github.head_ref }}
来检出源分支(我的情况仍然存在分离头问题)
所有回复都很好,但是我应该注意到有一个 GitHub 操作 Add & Commit 大大简化了流程。
name: Commit Date
on: push
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Create report file
run: date +%s > report.txt
- name: Commit changes
uses: EndBug/add-and-commit@v8
with:
author_name: Your Name
author_email: mail@example.com
message: 'Your commit message'
add: 'report.txt'
对于不定义用户或任何内容的自动提交,请使用 EndBug/add-and-commit@v7
。这是我的工作流程文件,用于自动格式化和提交 js 和 python
name: auto-format
on: push
jobs:
format-python:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: black
uses: lgeiger/black-action@v1.0.1
with:
args: .
- uses: EndBug/add-and-commit@v7
with:
default_author: github_actions
format-js:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: prettier
run: npx prettier --write "./**/*.{js,html}"
- uses: EndBug/add-and-commit@v7
with:
default_author: github_actions
我正在尝试从 GitHub 操作推送到 origin
远程。我的操作逻辑是:
- 处理
pull_request_review
事件并按评论消息过滤 - checkout 到 master,合并 PR 分支,运行 一些检查并推送到
origin
脚本是:
if [[ "${GITHUB_EVENT_NAME}" != "pull_request_review" ]]; then
echo "unsupported event: ${GITHUB_EVENT_NAME}"
exit 1
fi
user=$(jq -r .review.user.login ${GITHUB_EVENT_PATH})
cmd=$(jq -r .review.body ${GITHUB_EVENT_PATH})
echo "reviewer is ${user}, command is ${cmd}"
if [[ "${cmd}" == "merge" ]]; then
head=$(jq -r .pull_request.head.ref ${GITHUB_EVENT_PATH})
git config user.email test@test.com
git config user.name test
git checkout -B _tmp origin/${head}
git checkout -B master origin/master
git merge --no-ff _tmp
git push origin master
fi
我运行从 alpine:3.10
Docker 容器
FROM alpine:3.10
LABEL "com.github.actions.name"="Hello world action"
LABEL "com.github.actions.icon"="shield"
LABEL "com.github.actions.color"="green"
WORKDIR /app
COPY action.sh action.sh
RUN apk --update add bash git jq
CMD ["bash", "/app/action.sh"]
第一步工作正常(签出和合并),但操作未能将合并推送到 origin
,因为错误:
+ git push origin master
fatal: could not read Username for 'https://github.com': No such device or address
看起来 GitHub-action Docker 容器未配置为推送到 GitHub。我该如何配置它?是否可以使用 GitHub 提供的一些 env variables 或者一些挂载的文件(比如 /github/*
路径)?
您可以使用 secrets.GITHUB_TOKEN
作为存储库 URL 的密码。因此,您可以在 git push
行之前添加:
git remote set-url --push origin https://your_username:$GITHUB_TOKEN@github.com/your/repo
这假设您已经将 GITHUB_TOKEN 秘密作为环境变量传递给您的脚本。如果不是,请添加:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
到您的工作流程步骤。
actions/checkout@v2
版本 2 的结帐解决了分离的 HEAD 状态问题并简化了推送到源的过程。
name: Push commit
on: push
jobs:
report:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Create report file
run: date +%s > report.txt
- name: Commit report
run: |
git config --global user.name 'Your Name'
git config --global user.email 'your-username@users.noreply.github.com'
git commit -am "Automated report"
git push
如果您需要推送事件来触发其他工作流程,请使用 repo
作用域 Personal Access Token。
- uses: actions/checkout@v2
with:
token: ${{ secrets.PAT }}
actions/checkout@v1(原答案)
为@rmunn 的出色回答添加更多细节。问题是 actions/checkout@v1
操作使 git 存储库处于分离的 HEAD 状态。有关详细信息,请参阅此问题:https://github.com/actions/checkout/issues/6
这里有一个完整的例子来演示如何将签出的存储库变为可用状态并推送到远程。
name: Push commit
on: push
jobs:
report:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Create report file
run: date +%s > report.txt
- name: Commit report
run: |
git config --global user.name 'Your Name'
git config --global user.email 'your-username@users.noreply.github.com'
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY
git checkout "${GITHUB_REF:11}"
git commit -am "Automated report"
git push
要包含未跟踪的(新)文件,请更改工作流程以使用以下内容。
git add -A
git commit -m "Automated report"
以上工作流程应该适用于大多数活动。对于 on: pull_request
工作流程,应检出合并分支 (GITHUB_HEAD_REF
) 以替换默认的合并提交。
重要提示: 如果除了以下工作流程之外还有其他拉取请求检查,则必须使用 Personal Access Token 而不是默认的 GITHUB_TOKEN
。
这是由于 GitHub 操作故意施加的限制,即工作流引发的事件(例如 push
)无法触发进一步的工作流运行。
这是为了防止意外的“无限循环”情况,并作为一种反滥用措施。
使用 repo
作用域 Personal Access Token 是一种已批准的解决方法。有关解决方法的更多详细信息,请参阅此GitHub问题。
name: Push commit on pull request
on: pull_request
jobs:
report:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
with:
ref: ${{ github.head_ref }}
- name: Create report file
run: date +%s > report.txt
- name: Commit report
run: |
git config --global user.name 'Your Name'
git config --global user.email 'your-username@users.noreply.github.com'
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
git commit -am "Automated report"
git push
有关 on: pull_request
工作流程中推送到源的更多示例,请参阅此博客 post、GitHub Actions: How to Automate Code Formatting in Pull Requests。
所有提供的答案都是正确的。但我想对这些答案再补充一点。可能存在文件没有更改的情况。因此,在那种情况下,当尝试执行 git commit
命令时,它会 returns 导致 GitHub 工作流程失败的错误(失败的工作流程会阻止 PR 合并)。所以在commit之前我们要检查文件是否有变化。
name: Config Generator
on:
pull_request:
branches: [ main ]
jobs:
config-generator:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: ${{ github.head_ref }}
- name: Install jsonnet
run: sudo apt install -y jsonnet
- name: Generate probe configs
run: python3 generate-configs.py
- name: Check for modified files
id: git-check
run: echo ::set-output name=modified::$(if [ -n "$(git status --porcelain)" ]; then echo "true"; else echo "false"; fi)
- name: Update changes in GitHub repository
if: steps.git-check.outputs.modified == 'true'
run: |
git config --global user.name 'Your Name'
git config --global user.email 'Your Email for GitHub'
git add -A
git commit -m '[automated commit] add configs generated using jsonnet & GitHub workflow'
git push
以上工作流程是使用jsonnet和GitHub工作流程创建配置文件的示例。它首先安装 jsonnet 和 运行s 一个 python 脚本,该脚本使用 jsonnet 模板创建配置文件。如上所述,可能存在没有文件更改的情况。所以它使用 git status
命令来检查是否有任何文件更改。 (代替 git status
,也可以使用 git diff
。但它不会显示未跟踪的文件)。其余 git 命令 运行 仅当有文件更改时。
另请注意,即使我使用了 checkout@v2
,我也必须使用 ref: ${{ github.head_ref }}
来检出源分支(我的情况仍然存在分离头问题)
所有回复都很好,但是我应该注意到有一个 GitHub 操作 Add & Commit 大大简化了流程。
name: Commit Date
on: push
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Create report file
run: date +%s > report.txt
- name: Commit changes
uses: EndBug/add-and-commit@v8
with:
author_name: Your Name
author_email: mail@example.com
message: 'Your commit message'
add: 'report.txt'
对于不定义用户或任何内容的自动提交,请使用 EndBug/add-and-commit@v7
。这是我的工作流程文件,用于自动格式化和提交 js 和 python
name: auto-format
on: push
jobs:
format-python:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: black
uses: lgeiger/black-action@v1.0.1
with:
args: .
- uses: EndBug/add-and-commit@v7
with:
default_author: github_actions
format-js:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: prettier
run: npx prettier --write "./**/*.{js,html}"
- uses: EndBug/add-and-commit@v7
with:
default_author: github_actions