Skip to content

Commit 53e7cce

Browse files
authored
CM-26624-add-dockerhub-github-action (#5)
1 parent c62404e commit 53e7cce

File tree

7 files changed

+104
-85
lines changed

7 files changed

+104
-85
lines changed

.github/workflows/docker-image.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: ci
2+
3+
on:
4+
release:
5+
types:
6+
- created
7+
8+
jobs:
9+
docker:
10+
runs-on: ubuntu-latest
11+
steps:
12+
-
13+
name: Set up QEMU
14+
uses: docker/setup-qemu-action@v2
15+
-
16+
name: Set up Docker Buildx
17+
uses: docker/setup-buildx-action@v2
18+
-
19+
name: Login to Docker Hub
20+
uses: docker/login-action@v2
21+
with:
22+
username: ${{ secrets.DOCKERHUB_USERNAME }}
23+
password: ${{ secrets.DOCKERHUB_TOKEN }}
24+
-
25+
name: Build and push
26+
uses: docker/build-push-action@v4
27+
with:
28+
push: true
29+
tags: cycodehq/cycode_recovery_utils:latest

Dockerfile

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ WORKDIR /app
1111
COPY . /app/
1212

1313
# Install your Python dependencies
14-
RUN pip install --no-cache-dir PyGithub==1.57
15-
RUN pip install --no-cache-dir PyInquirer==1.0.3
16-
RUN pip install --no-cache-dir pydantic==1.10.2
14+
RUN pip install --no-cache-dir -r requirements.txt
1715

1816
# Command to run your Python console app
1917
CMD ["python", "main.py"]

README.md

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
- [Overview](#overview)
88
- [Features](#features)
99
- [Getting Started](#getting-started)
10-
- [Usage](#usage)
1110
- [Configuration](#configuration-file)
11+
- [Usage](#usage)
1212
- [License](#license)
1313

1414
## Overview
@@ -25,27 +25,11 @@ remain resilient even when faced with adversity.
2525

2626
## Getting Started
2727

28-
As easy as 1-2-3!
29-
1. Clone this repository
30-
2. Build your local docker image
31-
```
32-
docker build -t cycode_recovery_tool . --no-cache
33-
```
34-
3. Run the docker image
35-
```
36-
docker run -ti cycode_recovery_tool
37-
```
38-
39-
## Usage
40-
41-
1. Choose recovery action (currently only Release Block Pr) ![recovery action](./docs/recovery_action.png)
42-
2. Provide path for the configuration file (or use our default config.json file)
43-
3. Choose provider (currently only Github)
44-
4. Choose which status checks to release ![status_checks_release](./docs/status_checks_release.png)
28+
### Configuration File
4529

46-
## Configuration File
30+
The tool expects a configuration file with SCM information named `config.json`. You can either add this config file when you build the docker image or mount the configuration file with `docker run -v`.
4731

48-
There is a sample config file added to the project
32+
Sample config file:
4933

5034
```
5135
[
@@ -76,6 +60,34 @@ There is a sample config file added to the project
7660
* In case `organizations` are provided, we will update all the organization's default branch in all repositories.
7761
* You can provide multiple SCM configurations.
7862

63+
There are 2 options to run the Cycode recovery tool:
64+
* Using our docker image
65+
* Building your own docker image
66+
67+
### Pulling Cycode image
68+
```
69+
docker pull cycodehq/cycode_recovery_utils:latest
70+
```
71+
72+
### Building an image locally
73+
```
74+
docker build -t cycode_recovery_tool . --no-cache
75+
```
76+
77+
### Running the docker image
78+
You will need to provide your configuration file
79+
```
80+
docker run -v /path/to/file/config.json:/app/config.json -ti cycode_recovery_tool
81+
```
82+
83+
## Usage
84+
85+
1. Choose recovery action (currently only Release Block Pr)
86+
![recovery action](./docs/recovery_action.png)
87+
2. Choose provider (currently only GitHub)
88+
3. Choose which status checks to release
89+
![status_checks_release](./docs/status_checks_release.png)
90+
7991
## License
8092

81-
This project is licensed under the [MIT License](LICENSE).
93+
This project is licensed under the [MIT License](LICENSE).

config.json

Lines changed: 0 additions & 21 deletions
This file was deleted.

consts.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
config_file = "config.json"
2-
github = "Github"
2+
github = "GitHub"
33
providers = [github]
44
contexts = ["Cycode: Secrets",
55
"Cycode: IaC",

main.py

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,67 @@
1-
from typing import Dict
1+
import os
2+
from typing import Dict, List
23

4+
import pydantic
35
from PyInquirer import prompt
46

57
from consts import providers, contexts, config_file
68
from logger import logger
79
from menus.menu_base import MenuBase
810
from menus.release_block_pr_menu import ReleaseBlockPrMenu
11+
from release_block_pr_config import ReleaseBlockPrConfig
912

1013
release_block_pr_menu = ReleaseBlockPrMenu()
1114
menus = [release_block_pr_menu]
1215
menu_value_to_class: Dict[str, MenuBase] = {menu.get_menu(): menu for menu in menus}
1316

1417
main_menu = [
1518
{
16-
'type': 'list',
17-
'name': 'menu',
18-
'message': 'What would you like to do?',
19-
'choices': [menu for menu in menu_value_to_class.keys()],
19+
"type": "list",
20+
"name": "menu",
21+
"message": "What would you like to do?",
22+
"choices": [menu for menu in menu_value_to_class.keys()],
2023

2124
},
2225
{
23-
'type': 'input',
24-
'name': 'config_file',
25-
"message": "Please provide a configuration file",
26-
"default": config_file,
27-
'validate': release_block_pr_menu.validate_config_file,
28-
"when": release_block_pr_menu.menu_chosen
29-
},
30-
{
31-
'type': 'list',
32-
'name': 'provider',
26+
"type": "list",
27+
"name": "provider",
3328
"message": "Which SCM provider?",
3429
"choices": providers,
3530
"when": release_block_pr_menu.menu_chosen,
3631
},
3732
{
38-
'type': 'checkbox',
39-
'name': 'contexts',
33+
"type": "checkbox",
34+
"name": "contexts",
4035
"message": "Which status checks?",
4136
"choices": [{"name": context} for context in contexts],
4237
"when": release_block_pr_menu.menu_chosen
4338
}
4439
]
4540

46-
if __name__ == '__main__':
47-
answer = prompt(main_menu)
48-
menu = menu_value_to_class.get(answer.get('menu'))
49-
if menu:
50-
menu.handle(answer)
51-
logger.info("Completed successfully")
41+
42+
def validate_config_file():
43+
if not os.path.isfile(config_file):
44+
print("Files in /app directory:", os.listdir("/app"))
45+
return f"Could not find '{config_file}' file in the directory {os.getcwd()}"
46+
try:
47+
parsed_configs = pydantic.parse_file_as(List[ReleaseBlockPrConfig], config_file)
48+
for parsed_config in parsed_configs:
49+
if len(parsed_config.organizations) == 0 and len(parsed_config.repositories) == 0:
50+
return f"Invalid input, need at least one repository or organization"
51+
except Exception as e:
52+
return f"Invalid input, not in the expected format {e}"
53+
return True
54+
55+
56+
if __name__ == "__main__":
57+
validation_result = validate_config_file()
58+
if validation_result is not True:
59+
logger.error(validation_result)
5260
else:
53-
logger.error(f"invalid menu {answer.get('menu')}")
61+
answer = prompt(main_menu)
62+
menu = menu_value_to_class.get(answer.get("menu"))
63+
if menu:
64+
menu.handle(answer)
65+
logger.info("Completed successfully")
66+
else:
67+
logger.error(f"Invalid menu {answer.get('menu')}")

menus/release_block_pr_menu.py

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import pydantic
55

6-
from consts import github
6+
from consts import github, config_file
77
from logger import logger
88
from menus.menu_base import MenuBase
99
from providers.github_handler import GithubHandler
@@ -21,7 +21,7 @@ def handle(self, answers):
2121
if answers.get("provider") in self.handlers:
2222
handler_class = self.handlers[answers["provider"]]
2323
release_block_pr_configs: List[ReleaseBlockPrConfig] = pydantic.parse_file_as(List[ReleaseBlockPrConfig],
24-
answers["config_file"])
24+
config_file)
2525
for release_block_pr_config in release_block_pr_configs:
2626
handler = handler_class(release_block_pr_config.token)
2727
repositories: List[RepositoryConfig] = []
@@ -42,16 +42,3 @@ def handle(self, answers):
4242

4343
def get_menu(self):
4444
return release_block
45-
46-
@staticmethod
47-
def validate_config_file(config_file):
48-
if not os.path.isfile(config_file):
49-
return "File does not exist"
50-
try:
51-
parsed_configs = pydantic.parse_file_as(List[ReleaseBlockPrConfig], config_file)
52-
for parsed_config in parsed_configs:
53-
if len(parsed_config.organizations) == 0 and len(parsed_config.repositories) == 0:
54-
return f"Invalid input, need at least one repository or organization"
55-
except Exception as e:
56-
return f"Invalid input, not in the expected format {e}"
57-
return True

0 commit comments

Comments
 (0)