Skip to content

Commit

Permalink
Change GitHub api endpoint (#2)
Browse files Browse the repository at this point in the history
* Feature/add options (#1)

* add 'add' action and ghBaseUrl

* use env for base url

* update nodejs ver 12 to 16

* revert dist/index.js to upstream's one
  • Loading branch information
afrocandy authored May 15, 2023
1 parent e80fef9 commit 02e83a2
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 42 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ This action will set / delete Branch Protection rules on specified branches of G
"enforce_admins": true,
"required_linear_history": true,
"required_pull_request_reviews": {
"dismiss_stale_reviews": true
"dismiss_stale_reviews": true
}
},
"main": {
Expand All @@ -40,7 +40,7 @@ This action will set / delete Branch Protection rules on specified branches of G
"enforce_admins": null,
"required_linear_history": null,
"required_pull_request_reviews": {
"dismiss_stale_reviews": true
"dismiss_stale_reviews": true
}
}
}
Expand All @@ -53,8 +53,8 @@ This action will set / delete Branch Protection rules on specified branches of G
**Description** - Path of the text file(.txt) with repos to be excluded from branch protection. Specify every repo name (without org/ prefix) on a new line. This is optional. If not provided, no repos will be excluded and branch protection will be applied on all the repos within the organization.

### `action`
**Description** - This GitHub Custom action can be used to set / delete branch protection. The default value is set (if not specified). If delete is assigned, it will remove branch protection from every repo, if branch protection is already applied.
**Default** - 'set'
**Description** - This GitHub Custom action can be used to set / add / delete branch protection. The default value is set (if not specified). If add is assigned, it will add branch protection to every repo, if branch protection is not applied. If delete is assigned, it will remove branch protection from every repo, if branch protection is already applied.
**Default** - 'set'


# Usage
Expand Down
4 changes: 2 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ inputs:
excludedReposPath:
description: 'Path of the file with repos (newline separated) to be excluded for branch protection. This is optional.'
action:
description: 'Set or Delete Branch protection. Default is set.'
description: 'Set or Add or Delete Branch protection. Default is set.'
default: 'set'
required: true

runs:
using: 'node12'
using: 'node16'
main: 'dist/index.js'

branding:
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "branch-protection",
"version": "1.0.0",
"version": "1.1.0",
"description": "Custom GitHub Action based on Node.js to set branch protection rules",
"main": "dist/index.js",
"scripts": {
Expand Down
65 changes: 31 additions & 34 deletions src/action.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const core = require('@actions/core');
const { request } = require("@octokit/request");
const { request: orgRequest } = require("@octokit/request");
const fs = require('fs')

var excludedReposPath = '';
Expand All @@ -12,29 +12,43 @@ async function run() {
excludedReposPath = core.getInput("excludedReposPath");
includedReposPath = core.getInput("includedReposPath");
const action = core.getInput("action");
const limit = 100;
const canDeleteProtection = action == 'set' || action == 'delete';
const canSetProtection = action == 'set' || action == 'add';

var rulesObj;
var branches;
try {
if(!fs.existsSync(rulesPath)){
throw "Rules JSON is missing."
}

const request = orgRequest.defaults({
baseUrl: process.env.GITHUB_API_URL || 'https://api.github.com',
headers: {
authorization: "token " + token,
},
})
const rules = fs.readFileSync(rulesPath, {encoding:'utf8', flag:'r'});
rulesObj = JSON.parse(rules);
keys = Object.keys(rulesObj);
var repos = await getFinalRepos(token, orgName);
var repos = await getFinalRepos(request, orgName);
for (let i = 0; i < repos.length; i++) {
branches = await getBranches(token, repos[i], keys);
branches = await getBranches(request, repos[i], keys);
for (let j = 0; j < branches.length; j++) {
if(branches[j].protected){
if (!canDeleteProtection) {
console.log("Skip Branch Protection for " + branches[j].name + " branch of " + repos[i]);
continue;
}

console.log("Deleting Branch Protection for " + branches[j].name + " branch of " + repos[i]);
core.debug("Deleting Branch Protection for " + branches[j].name + " branch of " + repos[i]);
await deleteProtection(token, repos[i], branches[j].name);
await deleteProtection(request, repos[i], branches[j].name);
}
if(action == "set"){
if(canSetProtection){
console.log("Setting Branch Protection for " + branches[j].name + " branch of " + repos[i]);
core.debug("Setting Branch Protection for " + branches[j].name + " branch of " + repos[i]);
await setProtection(token, repos[i], branches[j].name, rulesObj[branches[j].name] )
await setProtection(request, repos[i], branches[j].name, rulesObj[branches[j].name] )
}
}
}
Expand All @@ -45,7 +59,7 @@ async function run() {
}
}

async function setProtection(token, repoName, branchName, ruleData){
async function setProtection(request, repoName, branchName, ruleData){
const url = "/repos/" + repoName + "/branches/" + branchName + "/protection"
if(ruleData == ""){
ruleData = {
Expand All @@ -58,9 +72,6 @@ async function setProtection(token, repoName, branchName, ruleData){
}
try {
const result = await request("PUT " + url, {
headers: {
authorization: "token " + token,
},
data: ruleData
});
//console.log(result.data);
Expand All @@ -72,14 +83,10 @@ async function setProtection(token, repoName, branchName, ruleData){
}
}

async function deleteProtection(token, repoName, branchName){
async function deleteProtection(request, repoName, branchName){
const url = "/repos/" + repoName + "/branches/" + branchName + "/protection"
try{
const result = await request("DELETE " + url, {
headers: {
authorization: "token " + token,
}
});
const result = await request("DELETE " + url);
if(result.status != 204){
throw "Exception occured during Delete Protection";
}
Expand All @@ -90,15 +97,11 @@ async function deleteProtection(token, repoName, branchName){
}
}

async function getBranches(token, repoName, branchNames){
async function getBranches(request, repoName, branchNames){
branchInfoArr = [];
const url = "/repos/" + repoName + "/branches"
try {
const result = await request("GET " + url, {
headers: {
authorization: "token " + token,
}
});
const result = await request("GET " + url);
branchData = result.data;
for (let j = 0; j < branchData.length; j++) {
const element = branchData[j];
Expand All @@ -114,13 +117,10 @@ async function getBranches(token, repoName, branchNames){
return branchInfoArr;
}

async function getRepoCount(token, orgName){
async function getRepoCount(request, orgName){
repoCnt = 0;
try {
const result = await request("GET /orgs/{org}/repos", {
headers: {
authorization: "token " + token,
},
org: orgName,
per_page:1,
type: "all"
Expand All @@ -140,13 +140,10 @@ function getPageCount(itemCount, limit){
return pageCount;
}

async function getPagedRepos(token, orgName, pageNum, limit){
async function getPagedRepos(request, orgName, pageNum, limit){
var repos = [];
try {
const result = await request("GET /orgs/{org}/repos", {
headers: {
authorization: "token " + token,
},
org: orgName,
per_page:limit,
type: "all",
Expand All @@ -163,7 +160,7 @@ async function getPagedRepos(token, orgName, pageNum, limit){
return repos;
}

async function getFinalRepos(token, orgName){
async function getFinalRepos(request, orgName){
repos = [];
includedRepos = [];
limit = 100;
Expand All @@ -175,12 +172,12 @@ async function getFinalRepos(token, orgName){
}
return includedRepos;
}
repoCount = await getRepoCount(token, orgName);
repoCount = await getRepoCount(request, orgName);
pageCnt = getPageCount(repoCount, limit);
excludedRepos = getReposFromFile(excludedReposPath);
for (let i = 0; i < pageCnt; i++) {
i = i + 1;
pagedRepos = await getPagedRepos(token, orgName, i, limit);
pagedRepos = await getPagedRepos(request, orgName, i, limit);
for (let j = 0; j < pagedRepos.length; j++) {
repoShortName = pagedRepos[j].replace(orgName + "/","");
if(!excludedRepos.includes(repoShortName)) {
Expand Down

0 comments on commit 02e83a2

Please sign in to comment.