-
Notifications
You must be signed in to change notification settings - Fork 9
Contributing Guidelines
- Setup Surface Locally
- Contributing to Surface (after you setup it locally)
- Dependencies
- Troubleshooting
- Specific Surface modules
The following sections covers a fully detailed list of steps on how to set up and start Surface locally. The first sections are both useful for development but also for users, if they desire to not use Docker.
- Make sure you have Python 3.9 or higher
- https://www.python.org/downloads/
-
brew install python3.9(restart the Terminal/iTerm after the installation is completed) apt install python3.9- ...
-
git clone git@github.com:surface-security/surface.git(ssh config is required - https://docs.github.com/en/authentication/connecting-to-github-with-ssh) cd ./surface- Install OS dependencies
- macOS -
brew install openssl mysql freetds - macOS -
xcode-select --install - if macOS Catalina (10.15): read this - https://stackoverflow.com/questions/58272830/python-crashing-on-macos-10-15-beta-19a582a-with-usr-lib-libcrypto-dylib
- Ubuntu/Debian (Linux) -
sudo apt-get install openssl libssl-dev libldap2-dev libsasl2-dev libmysqlclient-dev(for Kali, replace libmysqlclient-dev with default-libmysqlclient-dev)
- macOS -
- Upgrade your pip -
python3 -m pip install --upgrade pip - Create and activate virtual environment: using default
venv, for instance:# MacOS / Linux: python3 -m venv venv3 source venv3/bin/activate # Windows: python3 -m venv venv3 venv3\Scripts\activate.bat - Install requirements:
python3 -m pip install -r requirements_dev.txtIf macOS use
export LDFLAGS=-L/usr/local/opt/openssl/libbefore the previous the commands above
Also in macOS, read https://dev.to/ruivieira/fixing-libcrypto-ansible-crashes-on-macos-mm2 - Create local env file for variables, usernames, passwords:
touch local.env - (Optional) Default Surface configuration will use a SQLite file which is enough for most development purposes. If you'd rather use MySQL in Docker:
- Create MySQL docker container
bash ../dev/1-create_mysql_container.sh - Add the mysql config in local.env
SURF_DATABASE_URL=mysql://root:@127.0.0.1:3306/surface SURF_DATABASE_PASSWORD=""
- Create MySQL docker container
- Apply all migrations to the database
python3 manage.py migrate - You can create a super user with
python3 manage.py createsuperuser - Run the application:
python3 manage.py runserver - Log in with your created super user account.
Note: You can exit the virtual environment with
deactivate.
Note: there are many virtualenv options out there if you don't like
venv, it's just the default one.virtualenvwrapper-win,hatch,pyenv, or any other will do just fine.
Sample .vscode/settings.json that includes:
- autocomplete, pytest, sonarqube link, autoformatting (
black) and some exclusions from tree browser
{
"python.autoComplete.extraPaths": [
"surface",
],
"python.analysis.extraPaths": [
"surface",
],
"python.testing.pytestArgs": [
"surface",
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"python.formatting.provider": "black",
"files.exclude": {
"**/__pycache__": true,
"**/.pytest_cache": true,
"**/mysql.sql": true
}
}You can also use this launch.json example that includes Python debug config, Django's runserver and launchers for commands with and without arguments:
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Run Command",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/surface/manage.py",
"args": [
"${fileBasenameNoExtension}",
],
"django": true,
"justMyCode": false
},
{
"name": "Python: Run Command With 1 Arg",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/surface/manage.py",
"args": [
"${fileBasenameNoExtension}", "${input:someArgs}"
],
"django": true,
"justMyCode": false
},
{
"name": "Python: Run Command With 2 Args",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/surface/manage.py",
"args": [
"${fileBasenameNoExtension}", "${input:someArgs}", "${input:someArgs2}"
],
"django": true,
"justMyCode": false
},
{
"name": "Python: Django",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/surface/manage.py",
"args": [
"runserver"
],
"django": true,
"justMyCode": false
},
{
"name": "Debug Unit Test",
"type": "python",
"request": "test",
"justMyCode": false,
}
],
"inputs": [
{
"id": "someArgs",
"type": "promptString",
"description": "enter argument"
},
{
"id": "someArgs2",
"type": "promptString",
"description": "enter argument 2"
}
]
}Surface and their apps have a battery of unit tests what should be running green at all times. Before changing anything, make sure you have an healthy test environment by running the existing tests.
If you're using sqlite in Surface, no need to perform the below steps. For MySQL:
- Start MySQL (if you haven't already). With docker, that's as easy as:
docker-compose -f dev/docker-compose-dev.yml up mysql. - Make sure you have at least
SURF_DATABASE_URLset up insurface/local.env, which will tell Surface to use that database.
- if using MySQL from Docker:
SURF_DATABASE_URL=mysql://root:@127.0.0.1:23306/surface
- Run
pytestinside the root of the project:
- Using
-n4(multiprocessing for tests) option withpytestis recommended for a speedier run.
Please be a good citizen and write descriptive, short and concise commit messages. Run
pylintlocally, otherwise the style checks will fail and that could be avoided effortlessly.
- Create a new branch for your work:
git checkout -b my-awesome-branch - Write new code or make changes.
- If you're adding new functionality, use
python3 manage.py startappto automatically generate the correct file tree for you. - Add its code dependencies to
YOURAPP/requirements.txteven if they're already included by other apps (but make sure to mention same versions otherwisepipwill go crazy). These allow us to keep track of each app's dependencies and uses. - Update base requirements
surface/requirements.txtwith-r YOURAPP/requirements.txt. - If you do add an app-specific
requirements.txt, add thatADDline todocker/Dockerfilein the highlighted section.
- If you're adding new functionality, use
- Whenever you are editing anything in the models, make sure you run -
python3 manage.py makemigrationsto update the database tables. - After you have new migrations or you get new changes from Git, make sure you run again
python3 manage.py migratejust to update your table and make sure there are no incompatible changes being pushed. - Use a linter to check the quality of the code - we recommend Visual Studio code. Please try to fix the reported issues/warnings.
- Follow Code Style Guidelines section.
- Add all files you want to add to the repository -
git add <filename(s)>- Ideally, commits are brief messages explaining what is added to the project and should be easy to read as well. Avoid committing too many files simultaneously and avoid cryptic commit messages. Both make it harder to review.
-
Do not push your
local.envor any other sensitive file. In addition, even though mentioned in the Code Style Guidelines, do not push code with secrets in it.
- Commit your changes to your branch -
git commit -m "MESSAGE" - Push the new created branch to GitHub -
git push --set-upstream origin my-awesome-branch(you need to defined the upstream only at the first push) - Create a new Pull Request (PR) in GitHub from source as being your new branch
- After the PR is created and the pipeline is passing, assign the core team as reviewer because it is required to have at least one one approval to merge.
Surface can use mulitple stacks of services, like Elasticsearch, dkron, MySQL and the list continues to grow. Plus, you probably have your own. To create a working docker-compose for you, ensure that:
- Take a look at
dev/docker-compose-in-a-box.yml - Copy it to
dev/docker-compose.ymland make your own adjustments: Read the comments, comment or uncomment the services you don't want - Pay attention to the mentioned/required changes in your
local.env - Launch it with
docker-compose -f dev/docker-compose.yml up
Check scanners/CONTRIBUTING.md