Skip to content

Commit 59cd014

Browse files
authored
Merge pull request #75 from parteekcoder/contribute_action
Contribute action
2 parents b4d3b65 + ec607da commit 59cd014

6 files changed

Lines changed: 285 additions & 1 deletion

File tree

.github/workflows/pull_request.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Automatic Pull request
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
title:
7+
description: 'title of example'
8+
required: true
9+
body:
10+
description: 'description of example'
11+
required: true
12+
upstreamRepo:
13+
description: 'Upstream repo'
14+
required: true
15+
botRepo:
16+
description: 'bot repo'
17+
required: true
18+
repo:
19+
description: 'repo name'
20+
required: true
21+
22+
jobs:
23+
create-pull-request:
24+
runs-on: ubuntu-latest
25+
26+
steps:
27+
- name: Create PR
28+
run: |
29+
gh pr create --repo ${{ github.event.inputs.upstreamRepo }}/${{ github.event.inputs.repo }} --head ${{ github.event.inputs.botRepo }}:${{ github.ref }} --base main --title "${{ github.event.inputs.title }}" --body "${{ github.event.inputs.body }}"
30+
env:
31+
GITHUB_TOKEN: ${{ secrets.token }}

contribute

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/bash
2+
3+
# Check if the first 3 arguments are provided
4+
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then
5+
echo "Error: The first 3 arguments are mandatory."
6+
echo "Usage: ./contribute <Study-Name> <Full-Path-To-Study> <Author-Name> <Branch-Name> <PR-title> <PR-Body>"
7+
exit 1
8+
fi
9+
10+
# Set the last 3 arguments to "#" if not provided
11+
arg4=$4
12+
arg5=$5
13+
arg6=$6
14+
if [ -z "$4" ]; then
15+
arg4="#"
16+
fi
17+
if [ -z "$5" ]; then
18+
arg5="#"
19+
fi
20+
if [ -z "$6" ]; then
21+
arg6="#"
22+
fi
23+
python contribute.py $1 $2 $3 $arg4 $arg5 $arg6

contribute.bat

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
@echo off
2+
3+
REM Check if the first 3 arguments are provided
4+
if "%~1" == "" goto :missing_arg
5+
if "%~2" == "" goto :missing_arg
6+
if "%~3" == "" goto :missing_arg
7+
8+
REM Check and set default values for the last three arguments if not provided
9+
if "%~4"=="" (set arg4="#") else (set arg4=%~4)
10+
if "%~5"=="" (set arg5="#") else (set arg5=%~5)
11+
if "%~6"=="" (set arg6="#") else (set arg6=%~6)
12+
python contribute.py %1 %2 %3 %arg4% %arg5% %arg6%
13+
goto :eof
14+
15+
:missing_arg
16+
echo "Error: The first 3 arguments are mandatory."
17+
echo "Usage: ./contribute.bat <Study-Name> <Full-Path-To-Study> <Author-Name> <Branch-Name> <PR-title> <PR-Body>"
18+
19+
20+

contribute.py

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
import github
2+
from github import Github
3+
import os,sys,time,platform,base64
4+
5+
# Intializing the Variables
6+
# Hashed token
7+
BOT_TOKEN = 'Z2l0aHViX3BhdF8xMUFYS0pGVFkwUWVWZ3AzbkpkWk8yX3BOc1VncDFIVDMwZVNXcHhBNm9acHhMaGZGdU5CdE85TGpqdXF1UWRRNzI2S01aUk5HRUNGanFWNDZi'
8+
REPO_NAME = 'concore' #repo name
9+
OWNER_NAME = 'parteekcoder123' #bot account name
10+
STUDY_NAME = sys.argv[1]
11+
STUDY_NAME_PATH = sys.argv[2]
12+
AUTHOR_NAME = sys.argv[3]
13+
BRANCH_NAME = sys.argv[4]
14+
PR_TITLE = sys.argv[5]
15+
PR_BODY = sys.argv[6]
16+
UPSTREAM_OWNER = 'parteekcoder' # upstream to which examples should be contributed
17+
18+
19+
# Defining Functions
20+
def checkInputValidity():
21+
if AUTHOR_NAME=="" or STUDY_NAME=="" or STUDY_NAME=="":
22+
print("Please Provide necessary Inputs")
23+
exit(0)
24+
if not os.path.isdir(STUDY_NAME_PATH):
25+
print("Directory doesnot Exists.Invalid Path")
26+
exit(0)
27+
28+
29+
def getPRs(upstream_repo):
30+
try:
31+
return upstream_repo.get_pulls(head=f'{OWNER_NAME}:{BRANCH_NAME}')
32+
except Exception as e:
33+
print("Not able to fetch Status of your example.Please try after some time.")
34+
exit(0)
35+
36+
def printPR(pr):
37+
print(f'Check your example here https://github.com/{UPSTREAM_OWNER}/pulls/'+str(pr.number),end="")
38+
39+
def anyOpenPR(upstream_repo):
40+
pr = getPRs(upstream_repo)
41+
openPr=None
42+
for i in pr:
43+
if i.state=="open":
44+
openPr=i
45+
break
46+
return openPr
47+
48+
def commitAndUpdateRef(upstream_repo,repo,tree_content,commit,branch):
49+
try:
50+
new_tree = repo.create_git_tree(tree=tree_content,base_tree=commit.commit.tree)
51+
new_commit = repo.create_git_commit("commit message",new_tree,[commit.commit])
52+
if len(repo.compare(base=commit.commit.sha,head=new_commit.sha).files) == 0:
53+
print("Your don't have any new changes.May be your example is already accepted.If this is not the case try with different fields.")
54+
exit(0)
55+
ref = repo.get_git_ref("heads/"+branch.name)
56+
ref.edit(new_commit.sha,True)
57+
except Exception as e:
58+
print("failed to Upload your example.Please try after some time.",end="")
59+
exit(0)
60+
61+
62+
def appendBlobInTree(repo,content,file_path,tree_content):
63+
blob = repo.create_git_blob(content,'utf-8')
64+
tree_content.append( github.InputGitTreeElement(path=file_path,mode="100644",type="blob",sha=blob.sha))
65+
66+
67+
def fetchUpstream(repo,base_sha,branch):
68+
try:
69+
result = repo.compare(base=base_sha,head=branch.commit.commit.sha)
70+
if result.behind_by>0:
71+
ref = repo.get_git_ref("heads/"+branch.name)
72+
ref.edit(base_sha)
73+
except Exception as e:
74+
exit(0)
75+
76+
77+
def runWorkflow(repo,upstream_repo):
78+
openPR = anyOpenPR(upstream_repo)
79+
if openPR==None:
80+
workflow_runned = repo.get_workflow(id_or_name="pull_request.yml").create_dispatch(ref=BRANCH_NAME,inputs={'title':PR_TITLE,'body':PR_BODY,'upstreamRepo':upstream_repo,'botRepo':OWNER_NAME,'repo':REPO_NAME})
81+
if not workflow_runned:
82+
print("Some Error Occured.Please try after some time")
83+
exit(0)
84+
else:
85+
printPRStatus(upstream_repo)
86+
else:
87+
print("Successfully uploaded all files,your example is in waiting.Please wait for us to accept it.",end="")
88+
printPR(openPR)
89+
90+
def printPRStatus(upstream_repo):
91+
try:
92+
time.sleep(15)
93+
openPR = anyOpenPR(upstream_repo)
94+
if openPR==None:
95+
print("Someting went wrong or your example already exist.If this is not the case try with different fields")
96+
exit(0)
97+
printPR(openPR)
98+
except Exception as e:
99+
print("Your example successfully uploaded but unable to fetch status.Please try again")
100+
101+
102+
def isImageFile(filename):
103+
image_extensions = ['.jpeg', '.jpg', '.png']
104+
_, file_extension = os.path.splitext(filename)
105+
return file_extension.lower() in image_extensions
106+
107+
# Encode Github Token
108+
def encode_token(token):
109+
encoded_bytes = base64.b64encode(token.encode('utf-8'))
110+
encoded_token = encoded_bytes.decode('utf-8')
111+
return encoded_token
112+
113+
114+
# Decode Github Token
115+
def decode_token(encoded_token):
116+
decoded_bytes = base64.b64decode(encoded_token.encode('utf-8'))
117+
decoded_token = decoded_bytes.decode('utf-8')
118+
return decoded_token
119+
120+
121+
# check if directory path is Valid
122+
checkInputValidity()
123+
124+
125+
# Authenticating Github with Access token
126+
try:
127+
if BRANCH_NAME=="#":
128+
BRANCH_NAME=AUTHOR_NAME+"_"+STUDY_NAME
129+
if PR_TITLE=="#":
130+
PR_TITLE="Contributing Study "+AUTHOR_NAME+" "+STUDY_NAME
131+
if PR_BODY=="#":
132+
PR_BODY="Study Contributed by "+ AUTHOR_NAME
133+
AUTHOR_NAME = AUTHOR_NAME.replace(" ","_")
134+
DIR_PATH = AUTHOR_NAME + '_' + STUDY_NAME
135+
g = Github(decode_token(BOT_TOKEN))
136+
repo = g.get_user(OWNER_NAME).get_repo(REPO_NAME)
137+
upstream_repo = g.get_repo(f'{UPSTREAM_OWNER}/{REPO_NAME}') #controlcore-Project/concore
138+
base_ref = upstream_repo.get_branch(repo.default_branch)
139+
branches = repo.get_branches()
140+
BRANCH_NAME = BRANCH_NAME.replace(" ","_")
141+
DIR_PATH = DIR_PATH.replace(" ","_")
142+
is_present = any(branch.name == BRANCH_NAME for branch in branches)
143+
except:
144+
print("Some error occured.Authentication failed",end="")
145+
exit(0)
146+
147+
148+
try:
149+
# If creating PR First Time
150+
# Create New Branch for that exmaple
151+
if not is_present:
152+
repo.create_git_ref(f'refs/heads/{BRANCH_NAME}', base_ref.commit.sha)
153+
# Get current branch
154+
branch = repo.get_branch(branch=BRANCH_NAME)
155+
except Exception as e:
156+
print("Not able to create study for you.Please try again after some time",end="")
157+
exit(0)
158+
159+
160+
tree_content = []
161+
162+
try:
163+
for root, dirs, files in os.walk(STUDY_NAME_PATH):
164+
for filename in files:
165+
path = os.path.join(root, filename)
166+
if isImageFile(filename):
167+
with open(path, 'rb') as file:
168+
image = file.read()
169+
content = base64.b64encode(image).decode('utf-8')
170+
else:
171+
with open(path, 'r') as file:
172+
content = file.read()
173+
file_path = f'{DIR_PATH+path.removeprefix(STUDY_NAME_PATH)}'
174+
if(platform.uname()[0]=='Windows'): file_path=file_path.replace("\\","/")
175+
appendBlobInTree(repo,content,file_path,tree_content)
176+
commitAndUpdateRef(upstream_repo,repo,tree_content,base_ref.commit,branch)
177+
runWorkflow(repo,upstream_repo)
178+
except Exception as e:
179+
print("Some error Occured.Please try again after some time.",end="")
180+
exit(0)

fri/server/main.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from werkzeug.utils import secure_filename
33
import os
44
import subprocess
5-
from subprocess import call
5+
from subprocess import call,check_output
66
from pathlib import Path
77
import json
88
import platform
@@ -169,6 +169,35 @@ def clear(dir):
169169
resp.status_code = 500
170170
return resp
171171

172+
@app.route('/contribute', methods=['POST'])
173+
def contribute():
174+
try:
175+
data = request.json
176+
PR_TITLE = data.get('title')
177+
PR_BODY = data.get('desc')
178+
AUTHOR_NAME = data.get('auth')
179+
STUDY_NAME = data.get('study')
180+
STUDY_NAME_PATH = data.get('path')
181+
BRANCH_NAME = data.get('branch')
182+
if(platform.uname()[0]=='Windows'):
183+
proc=check_output(["contribute",STUDY_NAME,STUDY_NAME_PATH,AUTHOR_NAME,BRANCH_NAME,PR_TITLE,PR_BODY],cwd=concore_path,shell=True)
184+
else:
185+
proc = check_output(["./contribute",STUDY_NAME,STUDY_NAME_PATH,AUTHOR_NAME,BRANCH_NAME,PR_TITLE,PR_BODY],cwd=concore_path)
186+
output_string = proc.decode()
187+
status=200
188+
if output_string.find("/pulls/")!=-1:
189+
status=200
190+
elif output_string.find("error")!=-1:
191+
status=501
192+
else:
193+
status=400
194+
return jsonify({'message': output_string}),status
195+
except Exception as e:
196+
print(e)
197+
output_string = "Some Error occured.Please try after some time"
198+
status=501
199+
return jsonify({'message': output_string}),status
200+
172201
# to download /download/<dir>?fetch=<downloadfile>. For example, /download/test?fetchDir=xyz&fetch=u
173202
@app.route('/download/<dir>', methods=['POST', 'GET'])
174203
def download(dir):

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ numpy
55
scipy
66
matplotlib
77
cvxopt
8+
PyGithub

0 commit comments

Comments
 (0)