4

Learning Github Actions I'm finally able to call an action from a secondary repo, example:

org/action-playground

.github/workflows/test.yml

name: Test Write Action

on:
  push:
    branches: [main]

jobs:
  test_node_works:
    runs-on: ubuntu-latest
    name: Test if Node works
    strategy:
      matrix:
        node-version: [12.x]

    steps:
      - uses: actions/checkout@v2
        with:
          repository: org/write-file-action
          ref: main
          token: ${{ secrets.ACTION_TOKEN }} # stored in GitHub secrets created from profile settings
          args: 'TESTING'
      - name: action step
        uses: ./ # Uses an action in the root directory
        id: foo
        with:
          who-to-greet: 'Darth Vader'
      - name: output time
        run: |
          echo "The details are ${{ steps.foo.outputs.repo }}"
          echo "The time was ${{ steps.foo.outputs.time }}"
          echo "time: ${{ steps.foo.outputs.time }}" >> ./foo.md
        shell: bash

and the action is a success.

org/write-file-action

action.yml:

## https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions
name: 'Write File Action'
description: 'workflow testing'
inputs:
  who-to-greet: # id of input
    description: 'Who to greet'
    required: true
    default: './'
outputs:
  time: # id of output
    description: 'The time we greeted you'
  repo:
    description: 'user and repo'
runs:
  using: 'node12'
  main: 'dist/index.js'
branding:
  color: 'green'
  icon: 'truck' ## https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#brandingicon

index.js that is built to dist/index.js

fs = require('fs')
const core = require('@actions/core')
const github = require('@actions/github')

try {
  // `who-to-greet` input defined in action metadata file
  const nameToGreet = core.getInput('who-to-greet')
  console.log(`Hello ${nameToGreet}!`)

  const time = new Date().toTimeString()
  core.setOutput('time', time)

  const repo = github.context.payload.repository.full_name
  console.log(`full name: ${repo}!`)
  core.setOutput('repo', repo)

  // Get the JSON webhook payload for the event that triggered the workflow
  const payload = JSON.stringify(github.context.payload, undefined, 2)
  console.log(`The event payload: ${payload}`)

  fs.writeFileSync('payload.json', payload) // Doesn't write to repo
} catch (error) {
  core.setFailed(error.message)
}

package.json:

{
  "name": "wite-file-action",
  "version": "1.0.0",
  "description": "workflow testing",
  "main": "dist/index.js",
  "scripts": {
    "build": "ncc build ./index.js"
  },
  "dependencies": {
    "@actions/core": "^1.4.0",
    "@actions/github": "^5.0.0"
  },
  "devDependencies": {
    "@vercel/ncc": "^0.28.6",
    "prettier": "^2.3.2"
  }
}

but at current workflow nothing is created in action-playground. The only way I'm able to write to the repo is from a module using the API with github-api with something like:

const GitHub  = require('github-api')

const gh = new GitHub({
  token: config.app.git_token,
}, githubUrl)
const repo = gh.getRepo(config.app.repoOwner, config.app.repoName)
const branch = config.app.repoBranch
const path = 'README.md'
const content = '#Foo Bar\nthis is foo bar'
const message = 'add foo bar to the readme'
const options = {}
repo.writeFile(
  branch,
  path,
  content,
  message,
  options
).then((r) => {
  console.log(r)
})

and passing in the repo, org or user from github.context.payload. My end goal is to eventually read to see if it exists, if so overwrite and write to README.md a badge dynamically:

`![${github.context.payload.workflow}](https://github.com/${github.context.payload.user}/${github.context.payload.repo}/actions/workflows/${github.context.payload.workflow}.yml/badge.svg?branch=main)`

Second goal from this is to create a markdown file (like foo.md or payload.json) but I cant run an echo command from the action to write to the repo, which I get is Bash and not Node.

Is there a way without using the API to write to a repo that is calling the action with Node? Is this only available with Bash when using run:

- name: output
  shell: bash
  run: |
    echo "time: ${{ steps.foo.outputs.time }}" >> ./time.md

If so how to do it?

Research:

DᴀʀᴛʜVᴀᴅᴇʀ
  • 7,681
  • 17
  • 73
  • 127
  • You can directly use *git commands* inside you workflow with `run: |` to commit and push the changes you made on the repository ([here is an example](https://github.com/GuillaumeFalourd/poc-github-actions/blob/main/.github/workflows/19-push-event.yml) creating a `report.txt` file that way). Otherwise, it won't save / apply the changed performed by the action on the repository. – GuiFalourd Jul 14 '21 at 19:39
  • I copied `job1` and paste it to *test.yml* it works but goes into a continuous loop. Is there a way to pass an argument to the job for it then to run and am I required in bash to always use git config, add, commit and push on the `run` command? – DᴀʀᴛʜVᴀᴅᴇʀ Jul 14 '21 at 21:17
  • There might be some actions abstracting _git commands_ for you [on the marketplace](https://github.com/marketplace?type=actions). The continuous loop is probably related to the `push` trigger of your workflow, if you add other conditions, it won't trigger each time you push the file to the repository (you can for example add a `path-ignore` for this specific file, or change the trigger condition `on`). – GuiFalourd Jul 14 '21 at 22:10

0 Answers0