Skip to content

Commit

Permalink
first version of github action
Browse files Browse the repository at this point in the history
  • Loading branch information
aasmal97 committed Jun 18, 2024
1 parent d008ecd commit c7eb13d
Show file tree
Hide file tree
Showing 9 changed files with 4,112 additions and 1,045 deletions.
7 changes: 5 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ description: "Execute a GitHub Action only if the (triggering) actor is authoris
author: "Arky Asmal"
runs:
using: "node20"
main: "dist/index.js"
main: "dist/action/index.js"
branding:
icon: "briefcase"
color: "black"
inputs:
githubOrg:
required: false
description: "GitHub organization name, that you want to use to control access"
githubToken:
required: true
required: false
description: "GitHub access token with `repo` scope"
actor:
required: false
Expand Down
103 changes: 44 additions & 59 deletions action/index.ts
Original file line number Diff line number Diff line change
@@ -1,62 +1,36 @@
import * as core from "@actions/core";
import { z } from "zod";
import { GroupValues, InputValues } from "./types";
const InputZodSchema = z.object({
token: z
.string()
.optional()
.transform((val) => val || process.env.GITHUB_TOKEN),
actor: z
.string()
.optional()
.transform((val) => val || process.env.GITHUB_ACTOR || ""),
authorizedGroups: z
.string()
.optional()
.or(z.array(z.nativeEnum(GroupValues)))
.transform((val) => {
if (typeof val === "string") {
try {
const parsed = JSON.parse(val);
return parsed;
} catch (error) {
return [val];
}
}
return val;
})
.refine((val) => {
if (!val) return val;
return Array.isArray(val);
}),
authorizedActors: z
.string()
.optional()
.or(z.array(z.string()))
.transform((val) => {
if (typeof val === "string") {
try {
const parsed = JSON.parse(val);
return parsed;
} catch (error) {
return [val];
}
}
return val;
})
.refine((val) => {
if (!val) return val;
return Array.isArray(val);
}),
failSilently: z.boolean().default(false),
failureMessage: z
.string()
.default("Actor is not authorised to trigger this Workflow."),
});
const getInput = (): InputValues => {
import { InputZodSchema } from "./types";
import { Octokit } from "@octokit/rest";

async function getMembers(org: string, token: string) {
const octokit = new Octokit({
auth: token,
});
const membersList = await octokit.orgs.listMembers({
org,
});
const memberData: Promise<{
login: string;
role: string;
}>[] = membersList.data.map(async (member: any) => {
const membership = await octokit.orgs.getMembershipForUser({
org,
username: member.login,
});
return {
login: member.login as string,
role: membership.data.role as string,
};
});
return Promise.all(memberData);
}
const getInput = () => {
const results = {
githubToken: core.getInput("githubToken"),
githubOrg: core.getInput("githubOrg"),
actor: core.getInput("actor"),
authorizedActors: core.getInput("authorizedActors", { required: true }),
authorizedGroups: core.getInput("authorizedGroups"),
authorizedActors: core.getInput("authorizedActors"),
failSilently: core.getInput("failSilently") === "true" || false,
failureMessage:
core.getInput("failureMessage") ||
Expand All @@ -77,8 +51,9 @@ async function run(): Promise<void> {

try {
core.debug(`Reading input ...`);

const {
githubOrg,
githubToken,
actor,
authorizedActors,
failSilently,
Expand All @@ -88,11 +63,21 @@ async function run(): Promise<void> {

core.debug(`Got actor: ${actor}`);
core.debug(`Got a list of authorised actors ${authorizedActors}`);
core.debug(`Got a list of authorised groups ${authorizedGroups}`);
core.debug(`Got a token ${githubToken}`);
core.debug(`Got an org ${githubOrg}`);
const newAuthorizedActors = authorizedActors || [];

//handle access by organization
if (authorizedGroups && githubToken && githubOrg) {
const members = await getMembers(githubOrg, githubToken);
const users = members
.filter((m) => authorizedGroups.includes(m.role))
.map((m) => m.login);
newAuthorizedActors.push(...users);
}
const isAuthorisedActor = newAuthorizedActors.includes(actor);
core.setOutput("isAuthorisedActor", isAuthorisedActor);

core.setOutput("isAuthorisedActor", isAuthorisedActor);
core.debug(`isAuthorisedActor: ${isAuthorisedActor ? "Yes" : "No"}.`);
core.debug(`Fail silently? ${failSilently ? "Yes" : "No"}!`);

Expand Down
68 changes: 57 additions & 11 deletions action/types.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,65 @@
export enum GroupValues{
import { z } from "zod";
export enum GroupValues {
ADMIN = "admin",
OWNER = 'owner',
MEMBER = 'member'
OWNER = "owner",
MEMBER = "member",
}
export type Input = {
actor?: string;
authorisedActors: string[];
failSilently?: string;
failureMessage?: string;
};

export type InputValues = {
actor: string;
authorizedGroups?: GroupValues[]
authorizedActors?: string[];
failSilently: boolean;
failureMessage: string;
};
export const InputZodSchema = z.object({
githubOrg: z.string().optional(),
githubToken: z
.string()
.optional()
.transform((val) => val || process.env.GITHUB_TOKEN),
actor: z
.string()
.optional()
.transform((val) => val || process.env.GITHUB_ACTOR || ""),
authorizedGroups: z
.string()
.optional()
.or(z.array(z.nativeEnum(GroupValues)))
.transform((val) => {
if (typeof val === "string") {
try {
const parsed = JSON.parse(val);
return parsed;
} catch (error) {
return [val];
}
}
return val;
})
.refine((val) => {
if (!val) return val;
return Array.isArray(val);
}),
authorizedActors: z
.string()
.optional()
.or(z.array(z.string()))
.transform((val) => {
if (typeof val === "string") {
try {
const parsed = JSON.parse(val);
return parsed;
} catch (error) {
return [val];
}
}
return val;
})
.refine((val) => {
if (!val) return val;
return Array.isArray(val);
}),
failSilently: z.boolean().default(false),
failureMessage: z
.string()
.default("Actor is not authorised to trigger this Workflow."),
});
Loading

0 comments on commit c7eb13d

Please sign in to comment.