Github Actions variables point to fork parent - github-actions

I've forked a project:
and I'm setting up a CI definition on non master branches with these final steps:
- name: Zip the release
uses: papeloto/action-zip#v1
with:
files: README.md LICENSE *.dll nfive.yml nfive.lock fxmanifest.lua index.html config/
dest: ${{ github.workspace }}\nfive.zip
- name: Attach Zip as build artifact
uses: actions/upload-artifact#v1
with:
name: nfive
path: ${{ github.workspace }}\nfive.zip
Why does github.workspace point to the original repository NFive\NFive?
So, if run echo ${{ github.workspace }} it definitely shows the parent repository, but to make this even more difficult if I change directory to my organisation name and forked repository name I get this:
which is the output of these steps:
- run: echo ${{ github.workspace }}
- name: Move files to artifact folder
shell: pwsh
run: |
cd D:\a\HTB-5M\NFive
mkdir Build
Move-Item -Path README.md,LICENSE,*.dll,nfive.yml,nfive.lock,fxmanifest.lua,index.html,config -Destination Build
I don't have access to the parent path because I'm not a contributor, which is why I forked in the first place, so why does Github assume github.workspace should map to the parent?
=== Udate ===
So I reforked to my user account rather than the organisation I used and added a workflow step to just display the github.workspace variable and it definitely says the parent workspace D:\a\NFive\NFive
I tried changing the path in the nfive.yml
Same outcome
Deleting the nfive.yml doesn't change anything. I think the nfive.yml is actually used in the CI / CD pipelines the original authors configured on appveyor so it isn't going to affect anything here.

It isn't pointing to the fork parent repo, it's because the github.workspace variable follows this format: /home/runner/work/my-repo-name/my-repo-name.
That's the reason why NFive appears twice, it's NOT refering to NFive username / organization, but twice to the NFive repository name.
This is explained on the github documentation about default environment variables
I forked the repository as well and I don't get any error when running this workflow.
Here is the workflow run output with the generated .zip file artifact.

Related

Compare build artifacts from two different commits via github actions

I've got a workflow in github actions that automatically creates build artifacts and updates a single release with these new build artifacts every time I merge a PR into main (here's the repo).
I want to know if a new PR will cause a change in the build artifacts (specifically, there's just one CSV file that I care about). Sometimes these changes will be intentional, sometimes not, so I want something like a git diff between the CSV file before the PR and the CSV file after the PR.
I know I could setup a github action to:
checkout the old version of the code.
Run the code to generate the build artifacts
save the files of interest to disc
checkout the proposed version of the code from the PR
Run the PR code to generate the build artifacts
git diff the version before the PR to the version after the PR.
Format and write the git diff output as a comment to the PR, letting
me know about what changes there were so I can check that everything's ok manually.
But this seems like a really common problem and I can't believe there's not a simple
tool/solution out there already? Maybe some github action where you give it two SHAs, a command to run, and a list of files to git diff.
To be clear, these are build artifacts, so aren't tracked by git, and so solutions like git diff pullrequest main -- myfile.csv won't work.
Here is a solution that leverages git notes:
(In a nutshell, git notes allow you to CRUD metadata to a commit without touching the commit itself — and thus preserving history. Cf. § References below.)
Essentially, we want our workflow to:
Build the artefactsWe emulate this by running make build — to be adapted to your own scenario. For the sake of the example, we also assume that the build/ directory contains all and only the artefacts generated.
“Remember” the artefacts and their content (a so-called “artefacts summary”)We use the sha512sum shell command to create a mapping of artefacts' content (represented through their SHA sum) to their file name.We retrieve all artefacts via find results/ -type f, and then convert the mapping to a CSV with headers using sed 's/ /,/' | cat <(echo 'sha512,file_name') -
Attach the artefacts summary to the commitThat's where we leverage git notes, which allows us to add metadata to the commit ex-post, without modifying the history.
These steps should be executed for any commit on your main branch.
In case of a PR, you also want to repeat these steps on the branch's HEAD, plus:
Retrieve the artefacts summary of your PR's target branchSo you now have two artefacts summaries to compare: base (your main/master branch's one) and head (the branch of your PR). In the example below, the base is hard coded to main, but you could refine this by letting the workflow retrieve the target branch's name automatically.
Compare both artefacts summariesI've created the artefactscomparison Python package for that purpose. (Note: it's very much tailored to my use case and desiderata.)
Add the artefact comparison report to your PRBeebop, a bot will do that for you.
In the end, you should see something like on the screenshot above.
name: Artefacts Comparison
on:
push:
branches:
- main
pull_request:
branches:
permissions: write-all
jobs:
build_artefacts:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout#v3
with:
fetch-depth: 0
token: ${{ github.token }}
- name: Build artefacts
run: make build
- name: Generate artefacts summary
id: artefacts-summary
run: |
echo "ARTEFACTS_SUMMARY<<EOF" >> $GITHUB_OUTPUT
find build/ -type f -exec sha512sum {} \; | sed 's/ /,/' | cat <(echo 'sha512,file_name') - >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Add the artefacts summary as a git notes
run: |
git fetch origin refs/notes/*:refs/notes/*
git config user.name "github-actions"
git config user.email "bot#github.com"
git notes add -m "${{ steps.artefacts-summary.outputs.ARTEFACTS_SUMMARY }}"
git notes show
git push origin refs/notes/*
# In case of PR, add report of artefacts comparison
compare_artefacts:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'pull_request' }}
steps:
- name: Checkout
uses: actions/checkout#v3
with:
fetch-depth: 0
token: ${{ github.token }}
- name: Pull artefacts summaries (i.e., git notes) from upstream
run: |
git fetch origin refs/notes/*:refs/notes/*
- name: Retrieve PR's head branch's artefacts summary
id: artefact-summary-head
run: |
echo "ARTEFACTS_SUMMARY<<EOF" >> $GITHUB_OUTPUT
git notes show >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Retrieve PR's target branch's artefacts summary
id: artefact-summary-base
run: |
git checkout ${{ github.base_ref }}
echo "ARTEFACTS_SUMMARY<<EOF" >> $GITHUB_OUTPUT
git notes show >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Setup Python
uses: actions/setup-python#v4
with:
python-version: "3.10"
- name: Install artefactscomparison package
run: pip install -U artefactscomparison
- name: Generate artefact comparison report
id: artefact-comparison-report
run: |
echo "${{ steps.artefact-summary-head.outputs.ARTEFACTS_SUMMARY }}" > head.csv
echo "${{ steps.artefact-summary-base.outputs.ARTEFACTS_SUMMARY }}" > base.csv
echo "ARTEFACTS_REPORT<<EOF" >> $GITHUB_OUTPUT
artefacts_comparison -b base.csv -h head.csv >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Comment PR with artefact comparison report
uses: thollander/actions-comment-pull-request#v2
with:
message: ${{ steps.artefact-comparison-report.outputs.ARTEFACTS_REPORT }}
comment_tag: artefact_comparison_report
mode: recreate
needs: build_artefacts
References:
git notes documentation
How to sync (i.e. “pull” and push) git notes with upstream
git notes | Enhance Git Commit Messages with Notes
Git Notes: git's coolest, most unloved­ feature
Automatically add git notes via Github Actions

How to upload artifacts to existing release?

My workflow has automatic packaging and upload steps that package build artifacts and upload them to the workflow page. I also manually create releases.
I would like to do the following:
when I push to the tag that was created with a given release,
I would like to upload the zipped artifact file to that release, so users can download
the artifact. Any tips on how to do this ?
Here is my build yaml file.
Thanks!
Turns out it's dead simple to do this:
- name: upload binaries to release
uses: softprops/action-gh-release#v1
if: ${{startsWith(github.ref, 'refs/tags/') }}
with:
files: build/FOO.zip
It seems the action (softprops/action-gh-release#v1) mentioned also creates a release. But there is a much simpelere way upload an artifact to a release without the need of introducing action. The gh cli which is by default available on a GitHub hosted runners can upload the artifact for you.
assets:
name: upload assets
runs-on: ubuntu-latest
permissions:
contents: write # release changes require contents write
steps:
- uses: actions/checkout#v3
- name: Upload Release Asset
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run:
gh release upload <release_tag> <a_file>
Checkout full release example here.

Working Directory for local github actions in subdirectory

I'm trying to keep multiple github actions in the same monorepo using subdirectories, and run them like:
workflow.yml
// [...]
jobs:
run_my_script:
runs-on: ubuntu-latest
steps:
- name: Check out current repo
uses: actions/checkout#v2
- uses: ./my_action2
with:
my_input_var: "david"
./my_action2/action.yml
// [...]
runs:
using: "composite"
steps:
# Checkout files in this repo
- name: Checkout
uses: actions/checkout#v1
- name: Run myscript
run: python myscript.py "${{ inputs.my_input_var }}" # location: ./my_action2/myscript.py
shell: bash
The problem I'm having is that my action uses a python script in it's subdirectory, but the uses: action appears to run from the GITHUB_WORKING_DIR of the workflow and not the directory of the action itself.
python: can't open file 'myscript.py': [Errno 2] No such file or directory
I've looked through most of the working-directory questions surrounding github actions, but I'm still stumped.
I've also tried adding working-directory: ./my_action2 to the job's defaults: but it looks like it's not propagating to run: commands within the uses: step.
My workaround in the meantime has been to add an input for myaction2_working_directory in the workflow, and then add working-directory: ${{ inputs.myaction2_working_directory }} to every run: command in the action. This seems inelegant and repetitive. Is there a better way to do this?
contrary to the answer by Grzegorz, you cannot just run: cd foo and then expect all following steps to have a working directory of foo. as far as i can tell, the only way to do this is with the "workaround" the OP already posted -- add an input named e.g. working-directory to your action and then add working-directory: ${{ inputs.working-directory }} to every step. see https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsworking-directory
I had similar problem and for my composite actions I just added a first step as:
run: cd ${{ inputs.working_directory }}
and then all next steps are running in it.
I couldn't find a better way and having working-directory copy pasted was also something I didn't like.

How to automate and publish docs in CI (github actions)?

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>

##[error]No file matched with specific pattern: /appsettings.json

After reading this answer:this
I tried to do the same.
I have a .net core project and in my case, I am using a repo with a publish version so my appsettings.json is in the root of the repo.
# This is a basic workflow to help you get started with Actions
name: DeployToStaging
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
pull_request:
types: [assigned, opened, synchronize, reopened]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
FTP-Deploy-Action:
name: FTP-Deploy-Action
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2.1.0
with:
fetch-depth: 2
- uses: microsoft/variable-substitution#v1
with:
files: '${{env.DOTNET_ROOT}}/appsettings.json'
env:
ConnectionStrings.ToBudget: 'This is just a test'
- name: FTP Deploy
uses: SamKirkland/FTP-Deploy-Action#3.1.0
with:
ftp-server: <MyServer>
# FTP account username
ftp-username: <MyUsername>
ftp-password: ${{ secrets.FtpPassword }}
So basically I want to transform my connection string (for now it is just a test, in the future I will create a secret) and then push it to the server through FTP.
Everything is working except the variable substitution. The error is: No file matched with specific pattern: /appsettings.json
Any help would be much appreciated
Just found the issue.
instead of files: '${{env.DOTNET_ROOT}}/appsettings.json' I just need to do files: 'appsettings.json'
Now I am having a second issue. SamKirkland/FTP-Deploy-Action#3.1.0 doesn't like the change. It is avoiding uploading because the repo is dirty.
EDIT: regarding the second issue I moved to sebastionpopp/ftpaction