Coder Social home page Coder Social logo

ghat's Introduction

🛕 ghat

Reuse GitHub Actions workflows across repositories

On first run, ghat will copy a workflow from another GitHub repo. Successive runs will update the existing workflows and preserve the env variables.

  1. Write workflows once, use them in any repository
  2. Update your workflows without copy-pasting YAML
  3. Preserve local env variables
  4. Customize workflows before importing them

The good parts:

  • ghat does not run every time on your CI
  • ghat doesn't have to be a dependency of your project
  • ghat is node-based, but can install any type of workflows
  • Workflow changes need to be committed by the user, so you don't have to worry about it suddenly breaking "because of a dependency"

Requirements:

Usage

ghat uses degit to fetch any repository or specific YAML file/folder within it. Below you can find some examples using the workflows in fregante/ghatemplates.

$ ghat --help

  Description
    Reuse GitHub Actions workflows across repositories

  Usage
    $ ghat <source> [options]

  Options
    --exclude        Any part of the YAML file to be removed (can be repeated)
    --set            Value to add (can be repeated). The value is interpreted as YAML/JSON. Writing JSON on the CLI is tricky, so you might want to wrap the whole flag value
    -v, --version    Displays current version
    -h, --help       Displays this message

  Examples
    $ ghat fregante/ghatemplates/node
    $ ghat fregante/ghatemplates/node --exclude jobs.Build --exclude jobs.Test
    $ ghat fregante/ghatemplates/node --set on=push
    $ ghat fregante/ghatemplates/node --set 'jobs.Test.container=node:12.15'
    $ ghat fregante/ghatemplates/node-multi --set jobs.build.strategy.matrix.node-version=\[8.x,10.x\]
    $ ghat fregante/ghatemplates/node/build.yml

Fetch repo

If you provide a user/repo address, ghat will fetch the repository and look for *.yml/*.yaml files at the top level. If none are found, it will assume you want to copy the repo’s active workflows from .github/workflows

npx ghat fregante/ghat
# Copies *.yml OR .github/workflows/*.yml

Fetch whole folder

npx ghat fregante/ghatemplates/node
# Copies node/*.yml into the local .github/workflows. It's NOT recursive

Fetch specific file

npx ghat fregante/ghatemplates/node/ci.yml
# Copies node/ci.yml into the local .github/workflows/ci.yml

Customization

Exclude properties

You can exclude any property from the template by using the --exclude <path> flag, multiple times.

  • path is parsed by dot-prop, so refer to its documentation.
--exclude on.schedule

Set properties

You can set/overwrite any value with the --set <path>=<value> flag, multiple times.

  • path is parsed by dot-prop, so refer to its documentation.
  • value is a YAML/JSON value passed directly to the YAML parser.

Note: writing JSON on the command line is a little tricky, so if you're running into errors, try wrapping the whole flag value into a string, for example:

--set 'on.schedule=[{"cron": "42 17 * * 4"}]'

env object

When you fetch a workflow that already exists locally, the local file will be overridden, except for the top-level env object. For example:

Local file

env:
  ADJECTIVE: cool

# DO NOT EDIT BELOW - use `npx ghat fregante/workflows/demo`

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - run: echo My workflow is $ADJECTIVE

Template file

env:
  ADJECTIVE: the default

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - run: echo This new workflow is "$ADJECTIVE" since it was updated

Updated local file

Only the top-level env will be preserved, the rest will be updated.

env:
  ADJECTIVE: cool

# DO NOT EDIT BELOW - use `npx ghat fregante/workflows/demo`

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - run: echo This new workflow is "$ADJECTIVE" since it was updated

What’s ghat?

GitHub Actions Templating

I won’t pretend to know exactly what a Ghat is, but you should know check them out, they’re beautiful. 🇮🇳

License

MIT © Federico Brigante

ghat's People

Contributors

fregante avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

ghat's Issues

Add tests

Yes, this is the obligatory "we reaallly should add tests… soon" issue.

Automatically pickup and update existing templates

Running $ ghat without any sources should cause any existing templates to be updated. The update command for each is included in full in the header of each file. I think it can just load every file, parse the command, deduplicate any commands (because a command can generate multiple files, and then run them in parallel by calling itself)

This would enable users to update the templates by just calling ghat, without specifying each one separately.

Private repositories

Is there a way to fetch templates from a private repo? Is it possible to do so from a batch process? I saw #2 mentioned this, but it looks like that ticket was closed without being implemented.

The `--set` flag doesn't preserve the flag value’s quotations

Following #14

npx ghat fregante/ghatemplates/webext --set 'on.schedule=[{"cron": "42 17 * * 4"}]'

will be stored as

# DO NOT EDIT BELOW - use `npx ghat fregante/ghatemplates/webext --set on.schedule=[{"cron": "42 17 * * 4"}]`

without the ', which won't run correctly a second time.

Error: could not find commit hash for master

degit defaults to master for cloning, but new GitHub repositories use main as the default branch. I just set up a new repo and tried to use ghat, but get the following error:

(node:95712) UnhandledPromiseRejectionWarning: Error: could not find commit hash for master
    at Degit._cloneWithTar (/home/neo/ghat/node_modules/degit/dist/index-26d8486e.js:15037:10)
    at async Degit.clone (/home/neo/ghat/node_modules/degit/dist/index-26d8486e.js:14878:4)
    at async ghat (/home/neo/ghat/lib.js:63:2)
    at async /home/neo/ghat/bin.js:32:4

I could change the default branch of my repo, but I was wondering if you had a better solution?

Reproduction

  1. Set up a new GitHub repo for templates
  2. Try and use ghat elsewhere with this template repo
  3. See the following error: Error: could not find commit hash for master

ghat version: v0.11.1

Allow specifying a template name

If ghat fetches/finds a single template, it could also rename it to whatever the user prefers. Example:

npx ghat fregante/ghat/templates/node --out test.yml

But perhaps this could already be done, without issue, with #4:

# test.yml
apply: fregante/ghat/templates/node/ci.yml

Allow definition/setup via local template instead of cli

Currently the only customization possible is via the global env property, but unfortunately this isn't available everywhere in the workflow and can't be used to customize a workflow template.

I foresee a few ways to reuse existing templates:

Plain merging of a local template (e.g. .github/workflows-ghat/ci.yml) with the remote template

# Fetch template
apply: fregante/ghat/templates/node

# Overwrite existing `on` property with
on:
  - push

Importing single jobs

on:
  - push
jobs:
  test:
    name: Let's test stuff
    apply: fregante/ghat/templates/node#jobs.test # It would only merge the specific jobs.test section
  build:
    needs: test
    steps:
      - run: echo My other steps

An advanced way to customize the templates

For example it could apply some ENVs at merge time like GitHub does with the $default-branch variable:

  • because env doesn't support arrays for example, and can't be used in strategy.matrix
  • some conditions could be pre-evaluated, so that whole steps/jobs could be dropped/added at merge time instead of just being silenced at run time.

Initially defined in sindresorhus/project-ideas#128

Include some `degit` flags

ghat uses degit under the hood. It could include some flags, like mode=git, which enables getting workflows from private repos.

Allow local sources

ghat is currently build around degit, which only supports remote URLs.

Having it also support local paths would be useful, e.g.:

npx ghat /Users/fregante/Web/projects-modules/ghatemplates

The easy way to support this would be with absolute paths (starting with / or C:)

avoid comments?

Is there any way to disable adding the # FILE GENERATED WITH and # SOURCE comments besides --verbatim?

Adds `env: {}`

I ran npx ghat es-shims/Array.prototype.entries inside https://github.com/es-shims/Object.getPrototypeOf, and it added env: {} to the top of all my workflows, despite that not existing in the source. Can that be avoided?

(I realized that --verbatim will avoid this, but I'm not sure what consequences using that setting will have)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.