Skip to content

Commit

Permalink
New action: add-runtime-custom-property
Browse files Browse the repository at this point in the history
  • Loading branch information
thypon committed Jun 14, 2024
1 parent 3e7f487 commit f479966
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 0 deletions.
31 changes: 31 additions & 0 deletions actions/add-runtime-custom-property/action.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module.exports = async ({ github, context, inputs, actionPath, core, debug = false }) => {
const { default: kubeGetRepositories } = await import(`${actionPath}/src/kubeGetRepositories.js`)
const { default: updateRuntimeProperty } = await import(`${actionPath}/src/updateRuntimeProperty.js`)
const org = context.repo.owner

if (inputs.static_repositories) {
await updateRuntimeProperty({
github,
org,
runtime: 'static',
repositories: inputs.static_repositories,
debug
})
}

if (inputs.runtime_directory) {
const repositories = await kubeGetRepositories({
directory: inputs.runtime_directories,
orgFilter: new RegExp(`^${org}$`),
debug
})

await updateRuntimeProperty({
github,
org,
runtime: 'k8s',
repositories,
debug
})
}
}
40 changes: 40 additions & 0 deletions actions/add-runtime-custom-property/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# action that add runtime as a custom property
# to all repositories in this organization
name: add-runtime-custom-property
description: Add Runtime as Custom Property to Repositories
inputs:
github_token:
description: 'GitHub Token'
required: true
static_repositories:
description: 'Repositories that will have a `static` runtime'
required: true
runtime_directory:
description: 'Directory where runtime files are stored'
required: true
debug:
description: 'Debug mode'
required: false
runs:
using: 'composite'
steps:
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: '20.x'
- id: npm
run: cd ${{ github.action_path }}/../..; npm ci
shell: bash
- name: run
id: run
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
env:
DEBUG: ${{ (inputs.debug == 'true' || runner.debug) && 'true' || 'false'}}
with:
github-token: ${{ inputs.github_token }}
script: |
const actionPath = '${{ github.action_path }}/../../'
const inputs = ${{ toJson(inputs) }}
const script = require('${{ github.action_path }}/action.cjs')
await script({github, context, inputs, actionPath, core,
debug: process.env.DEBUG === 'true'})
46 changes: 46 additions & 0 deletions src/kubeGetRepositories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
export default async function kubeGetRepositories ({
debug = false,
orgFilter,
directory
}) {
if (!directory) {
throw new Error('directory is required!')
}

if (!orgFilter) {
orgFilter = /.*/
}

if (typeof orgFilter === 'string') {
orgFilter = new RegExp(orgFilter)
}

debug = debug === 'true' || debug === true

const fs = require('fs')
const yaml = require('js-yaml')
const glob = require('glob')

const files = glob.sync(`${directory}/**/*.yaml`)
const repos = []
for (const file of files) {
const content = fs.readFileSync(file, 'utf8')
yaml.loadAll(content, (doc) => {
if (doc && doc.kind === 'GitRepository' && doc.spec.url) {
repos.push(doc.spec.url)
}
})
}

const uniqueRepos = [...new Set(repos)].sort().map((url) => {
// url in the format of ssh://git@github.com/example-org/example-ops
// get the last two elements and return an object with organization and name
const parts = url.split('/')
const name = parts.pop()
const organization = parts.pop()

return { organization, name }
})

return uniqueRepos.filter(r => orgFilter.test(r.organization))
}
58 changes: 58 additions & 0 deletions src/updateRuntimeProperty.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
export default async function updateRuntimeProperty ({
githubToken = null,
github = null,
debug = false,
repositories,
runtime,
org
}) {
if (!github && githubToken) {
const { Octokit } = await import('octokit')

github = new Octokit({ auth: githubToken })
}

if (!github && !githubToken) {
throw new Error('either githubToken or github is required!')
}

if (!runtime) {
throw new Error('runtime is required!')
}

if (!repositories) {
throw new Error('repositories is required!')
}

if (!org) {
throw new Error('org is required! No token can modify more than one org property.')
}

debug = debug === 'true' || debug === true

// if repositories is a string, split it on spaces
if (typeof repositories === 'string') {
repositories = repositories.split(' ').map(r => r.trim()).map((r) => {
const s = r.split('/')
return { org: s[0], name: s[1] }
}).filter(r => r.org === org)
}

for (const repo of repositories) {
if (debug) { console.log(`updating runtime property for ${repo.org}/${repo.repo}`) }

await github.request('PATCH /orgs/{org}/properties/values', {
org: repo.org,
repository_names: [repo.name],
properties: [
{
property_name: 'runtime',
value: runtime
}
],
headers: {
'X-GitHub-Api-Version': '2022-11-28'
}
})
}
}

0 comments on commit f479966

Please sign in to comment.