Strivio
Strivio is a GitHub action that allows anyone to host competitive coding event directly on GitHub Repository like hackerrank, leetcode, etc. It is fun to use and quite simple. It also has the support of many programming languages such as c
, c++
, java
and python
You can check Strivio here on the GitHub marketplace.
https://github.com/marketplace/actions/strivio
Strivio is also OpenSourced on GitHub and here are the links for the action and the source code of the action.
Action Repo
- https://github.com/jainal09/strivio
Source Code
- https://github.com/jainal09/strivio-docker
Also, check out the docker image on docker hub
- https://hub.docker.com/r/jainal09/strivio
Introduction
Ever wondered that is it possible to host a competitive coding event on GitHub?
Well, it should be possible given the fact that GitHub provides CI / CD built-in through GitHub Action.
So, I decided wouldn't it be cool if I make a GitHub action that simply tests code by passing given sets of Inputs and checking it against given sets of outputs. Sounds simple right? Well, it's a kind of little complex!
You see, there are a few challenges I need to solve.
- Input and output test cases should be hidden somewhere and the participants of the events cannot see it.
- Multiple Programming Language Support
- And a system that should enable organizers to use the action without modifying the code.
- One GitHub action that can be used simultaneously many people around the world.
So, this is how it all went.
Idea Construction
So basically I created a rough idea of implementation like this:
my-python-script
------> user-code
------> compile and run
------> result
So, here first my python script identifies users' programming language. Then it compiles and runs the user's program by passing necessary inputs and storing outputs.
It then matches the outputs of the program with the output of the test cases. If all outputs are passed than tick
☑️ and if not than ✖️.
Solving Challenges
So, I thought if there is a way that input test cases magically appeared at run time and disappeared after that should solve my issue.
Hence, I used an amazing bash script known as the DropBox uploader.
https://github.com/andreafabrizi/Dropbox-Uploader
What it does is it allows anyone to download and upload files from their DropBox account from the terminal!
Sounds cool right. It also has many more cool features and I recommend you to have a look at this repository.
So, now organizers will simply upload input and output test cases on their DropBox drive and during the run time my script will download the input and output test cases through a unique token(dropbox API key) preventing visibility to the participants.
This solved my 2 challenges.
Input and output test cases should be hidden somewhere and the participants of the events cannot see it.
And a system that should enable organizers to use the action without modifying the code.
Still, 2 challenges needed to solve.
For multiple language support, I decided to stick it to simple and restrict the top 4 most popular competetive coding programming languages i.e python, java, cpp, and c.
The support to the programming languages can be solved by using docker with all the dependencies and compilers installed into a docker container.
Multiple Programming Language Support
And the last issue, allowing simultaneous use of action was solved by putting the DropBox API key as a GitHub secret and hence not hardcoding it in the code and hence anyone can use the action!
One GitHub action that can be used simultaneously many people around the world.
And that's how I solved all my challenges and issues.
Creating the action
So far the idea was clear to me and the challenges were so far sorted out.
Now it was coding time!
As mentioned earlier I needed a python script which I will compile the code for me and a docker container.
Here Is the basic code segment from my Code : https://github.com/jainal09/strivio-docker/blob/master/Evaluate.py
Organizers will upload a I/O test cases and then I will download it and create into python arrays inputs
and outputs
. Then I will iterate them and compile and pass inputs and compare outputs. Check out the below code.
for inp, outp in zip(inputs, outputs):
data, temp = os.pipe()
os.write(temp, bytes(str(inp), "utf-8"))
os.close(temp)
output = subprocess.check_output(
[
"python3",
os.path.abspath(
"program.py"
)
],
stdin=data
)
output = output.decode("utf-8")
output = re.sub('\s+', '', output)
outp = re.sub('\s+', '', str(outp))
if output == outp:
print("Test Case " + str(case) + ": Passed")
case = case + 1
else:
raise Exception(
"Test Case " + str(case) + ": Failed"
)
Done its as simple as that! You can check out the whole code base and other cool stuff which I did here
https://github.com/jainal09/strivio-docker
I am not explaining here each and every segment of it as it kind of makes sense right!
Okay Now How do I use it?
Organizers
- Head to DropBox Sign In/ Create account and then click on this link DropBox Developer Page
Alternate Link: https://www.dropbox.com/developers/documentation
- Click on App Console
- Click on Create App
- Click Full Dropbox
- Give any name to the app and Click create app
- After you Create your Dropbox App click on Generate Access token and Copy it.
This token is to be shared with participants. This works as a login access key for the competition.
- Create a File Known as 🗃️ "IO.yaml" for all the Input / Output Test Cases
- The File should Look like this
inputs:
input1:
1
input2:
2
input3:
3
input4:
4
input5:
5
outputs:
output1:
2
output2:
3
output3:
4
output4:
5
output5:
6
- Head to DropBox, Upload this
IO.yaml
to the Root Directory (not into any folder just upload it outside on dropbox) of Drop Box and done 😃! - Send the OATH token to participants.
Participants
- In GitHub Repo open Settings/Secrets and click on add a Secret
- The name of the secret should be OATH and value should be the access token which the organizer gave you!
Example:
This should look like this.
Now its time to start coding! Clone your repo and start working on the problem.
Supported Programming Languages
python, java, c++, c
Create a file program.extension - supported extension
.c .cpp .java .py
NOTE: for java Class name should be Main
After Coding is done create a file in repo 🗃️ "lang.yaml"
Add the below code.
language:
python3
- Replace the name of Programming Language in the above code as follows.
python - write python3
java - write java
c++ - write cpp
c - write c
No language other than above are supported!
Commit the code and push
Head to GitHub and select Actions
- Click on Set up a workflow yourself
- Delete everything and paste the below code
name: Evaluation
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Results
uses: jainal09/strivio@Production
with:
oath: ${{ secrets.oath }}
Click on start-commit
- Click on actions
- Click on your last commit, click build, wait for the Build jainal09/strivio@Production to turn green ✔️ and after that click on Results 🤞
- Check if your code passed all the Test Case ✔️ or ❌
☝️Successful Build with all Test Case Passed🤘.
☝️Build Failed as Code Didn't Pass all the Test Cases😬.
Sample Test Repo - https://github.com/jainal09/strivio-in-action
Done! that's how you can host a coding competition on GitHub like Hackerrank etc
What is the tech used here?
- GitHub (obviously!)
- GitHub actions
- Python
- Pyaml to parse the yaml files
- Dropbox-Uploader
- Docker
- Docker Hub for Continuous Deployment with my GitHub repo.
Limitation and Future Scopes
As we all know there is nothing perfect in this world.
So does Strivio! As the idea is just a proof of concept and not a competitor to the online coding platforms.
The following are the Limitations of the project:
Currently, only 1 question per repo is supported and I am working for more project support.
- I believe that input and output test cases format should be improved and also separated into 2 different txt files rather than yaml.
- Timing and space constraint features are not present.
- Testing against complex I/O test cases.
The following are the Future Scopes of the project:
- [ ] Add support for time and space constraints.
- [ ] Change Input output formats.
- [ ] And offcourse solve any created issues.
Top comments (2)
Really cool idea.
Thanks !