feat: Added a proper README; had fun with MermaidJS!
parent
9aa49c3c9b
commit
d76609d6d1
|
@ -32,5 +32,6 @@ Thumbs.db
|
||||||
.venv
|
.venv
|
||||||
|
|
||||||
# Local Developer Notes
|
# Local Developer Notes
|
||||||
dev
|
|
||||||
dist
|
dist
|
||||||
|
dev
|
||||||
|
.cache-trivy
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
dist
|
dist
|
||||||
|
dev
|
||||||
|
.cache-trivy
|
||||||
|
|
|
@ -16,4 +16,6 @@ ENV SERVER_PORT 8787
|
||||||
ENV SERVER_ROOT /app
|
ENV SERVER_ROOT /app
|
||||||
ENV SERVER_LOG_LEVEL info
|
ENV SERVER_LOG_LEVEL info
|
||||||
|
|
||||||
|
USER 5020
|
||||||
|
|
||||||
LABEL maintainer="s174509@dtu.dk"
|
LABEL maintainer="s174509@dtu.dk"
|
||||||
|
|
131
README.md
131
README.md
|
@ -1,3 +1,128 @@
|
||||||
# TODO
|
# DTU Python Support
|
||||||
- [ ] Don't use commit ID when tagging dev containers / check clean git tree before allowing a commit ID tag.
|
This is the repository containing the "DTU Python Support" book.
|
||||||
- [ ] `pre-commit install` as part of `run.sh`?
|
See it live: https://pysupport.timesigned.com.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
We've automated all the gnarly steps between beautiful `*.md` source files, and a real, running website.
|
||||||
|
|
||||||
|
You'll need to have the following commands available:
|
||||||
|
- `git`: <https://git-scm.com/>
|
||||||
|
- `python`: Newer than `3.9`.
|
||||||
|
- `podman`: <https://podman.io/>
|
||||||
|
- `pre-commit`: <https://pre-commit.com/>
|
||||||
|
- `echo "I am not afraid of the terminal!"`
|
||||||
|
|
||||||
|
Once that's set, go ahead and grab (`clone`, in `git` terms) this repo:
|
||||||
|
```bash
|
||||||
|
git clone https://git.sofus.io/so-rose/site-support.git
|
||||||
|
cd site-support
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, you can view the book in your local browser:
|
||||||
|
```bash
|
||||||
|
./run.py app
|
||||||
|
## Now, navigate to http://localhost:8787 in your browser.
|
||||||
|
## CTRL+C to exit.
|
||||||
|
```
|
||||||
|
|
||||||
|
Run this whenever you want to preview any changes you made to `src/*.md` files!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Structure of the Book
|
||||||
|
The book is structured to minimize technical wonk, and let you *focus on writing*.
|
||||||
|
This is made possible due to `mdbook`, this project avoids a lot of the technical boiler
|
||||||
|
|
||||||
|
## Easy Overview / ToC / Menu: `src/SUMMARY.md`
|
||||||
|
The beating heart of the book is [`src/SUMMARY.md`](./src/SUMMARY.md).
|
||||||
|
The headings, bullet nesting, and links result in the side-menu.
|
||||||
|
|
||||||
|
|
||||||
|
## Written in Markdown: A Gentler Take on Text
|
||||||
|
"Markdown" is text for humans. That's it!
|
||||||
|
|
||||||
|
This **entire book** is written in **100% normal** "Markdown".
|
||||||
|
The *only* filetype in `src/` is `*.md`.
|
||||||
|
|
||||||
|
All `.md` files can be opened in *any text editor*.
|
||||||
|
No, not Word; think Notepad, vim, VSCodium!
|
||||||
|
|
||||||
|
But what does it look like? Ya know, `.md` files?
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
It looks pretty normal, honestly.
|
||||||
|
You can **bold**, *italic*, and even write `cool_l33t_code`!
|
||||||
|
|
||||||
|
You'll need a [text editor of some kind](https://neovim.io/), of course.
|
||||||
|
But you'll find that super quick; after all, you are:
|
||||||
|
- Cool
|
||||||
|
- Knowledgeable
|
||||||
|
- Awesome
|
||||||
|
```
|
||||||
|
|
||||||
|
With a little bit of extension magic, like the built-in MermaidJS, you can even impress your cat!
|
||||||
|
```mermaid
|
||||||
|
journey
|
||||||
|
title Learning to Use site-support: A User Journey
|
||||||
|
section Utter Confusion
|
||||||
|
Find the Repo: 1: You, A Rus, A Kitten
|
||||||
|
Clone the Repo: 3: You, A Kitten
|
||||||
|
Notice it's all .md: 5: You
|
||||||
|
section Fun and Games
|
||||||
|
Discover ./run.py app: 7: You
|
||||||
|
Change stuff: 9: You
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Contributing
|
||||||
|
Let's say you've made some cool changes, and you want to propose they go into the book.
|
||||||
|
First of all, thank you!
|
||||||
|
But, how do?
|
||||||
|
|
||||||
|
At this point, you'll need to know a bit of `git`.
|
||||||
|
Incidentally, the book contains a quick guide at [`src/basics/collaboration/git`](./src/basics/collaboration/git)!
|
||||||
|
This git-powered puzzle game is also a surprisingly effective teacher: <https://learngitbranching.js.org/>
|
||||||
|
|
||||||
|
Armed with this knowledge, make a branch **within the repo folder**:
|
||||||
|
```bash
|
||||||
|
git checkout -b <branch_name>
|
||||||
|
git branch
|
||||||
|
```
|
||||||
|
You're now on a new branch, which belongs only to you!
|
||||||
|
|
||||||
|
Now, commit your changes. Remember to use [Conventional Commit](https://www.conventionalcommits.org/en/v1.0.0/) format for your commit message.
|
||||||
|
For example:
|
||||||
|
```bash
|
||||||
|
git add -A
|
||||||
|
git status ## Always review your changes!
|
||||||
|
git commit -m "feat: New page!"
|
||||||
|
```
|
||||||
|
That's it! Give it a `git push`.
|
||||||
|
|
||||||
|
All that's left is to start a [Pull Request](https://git.sofus.io/so-rose/site-support/pulls), and wait for someone on the team to examine your contribution.
|
||||||
|
|
||||||
|
When several people collaborate, the workflow might end up looking something like this:
|
||||||
|
```mermaid
|
||||||
|
gitGraph
|
||||||
|
commit
|
||||||
|
commit tag: "v0.1.0"
|
||||||
|
branch bobs-cool-new-feature
|
||||||
|
branch jills-hotfix
|
||||||
|
checkout bobs-cool-new-feature
|
||||||
|
commit
|
||||||
|
commit
|
||||||
|
commit
|
||||||
|
checkout jills-hotfix
|
||||||
|
commit
|
||||||
|
commit
|
||||||
|
checkout main
|
||||||
|
merge jills-hotfix tag: "v0.1.1"
|
||||||
|
merge bobs-cool-new-feature tag: "v0.2.0"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Conclusion
|
||||||
|
You should have everything you need to get started.
|
||||||
|
If anything is still confusing, don't hesitate to report an [Issue](https://git.sofus.io/so-rose/site-support/issues)!
|
||||||
|
|
71
run.py
71
run.py
|
@ -40,11 +40,11 @@ CMD_DEPENDENCIES = [
|
||||||
]
|
]
|
||||||
|
|
||||||
IMAGE_NAME = "site-support"
|
IMAGE_NAME = "site-support"
|
||||||
IMAGE_VERSION = ("0", "0", "1")
|
IMAGE_VERSION = ("0", "1", "0")
|
||||||
|
|
||||||
REGISTRY_HOST = "git.sofus.io"
|
REGISTRY_HOST = "git.sofus.io"
|
||||||
REGISTRY_USER = "so-rose"
|
REGISTRY_USER = "so-rose"
|
||||||
REGISTRY_PASSWORD = subprocess.check_output(
|
REGISTRY_PASSWORD = lambda: subprocess.check_output(
|
||||||
['pass', 'services/home/git.sofus.io/container-registry-token']
|
['pass', 'services/home/git.sofus.io/container-registry-token']
|
||||||
).decode('ascii').strip()
|
).decode('ascii').strip()
|
||||||
|
|
||||||
|
@ -52,18 +52,28 @@ REGISTRY_PASSWORD = subprocess.check_output(
|
||||||
# - Help Text
|
# - Help Text
|
||||||
####################
|
####################
|
||||||
def action_help() -> None:
|
def action_help() -> None:
|
||||||
print("""This script provides one-click development, CI, and deployment.
|
print(f"""This script provides one-click development, CI, and deployment,
|
||||||
|
to support the use of the {IMAGE_NAME} project.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
echo -e "./run.py [OPTION] [EXTRAS]"
|
echo -e "./run.py [OPTION] [EXTRAS]"
|
||||||
|
|
||||||
|
Program Information:
|
||||||
|
Version
|
||||||
|
=> {".".join(IMAGE_VERSION)}
|
||||||
|
OCI Container
|
||||||
|
=> {REGISTRY_HOST}/{REGISTRY_USER}/{IMAGE_NAME}:{IMAGE_VERSION[0]
|
||||||
|
|
||||||
The following commands must be available:
|
The following commands must be available:
|
||||||
podman
|
podman
|
||||||
=> The project is developed and run in podman containers.
|
=> This project is developed and run in podman containers.
|
||||||
|
=> https://podman.io/
|
||||||
git
|
git
|
||||||
=> This project uses git for versioning, and collaboration.
|
=> This project uses git for versioning, and collaboration.
|
||||||
|
=> https://git-scm.com/
|
||||||
pre-commit
|
pre-commit
|
||||||
=> Enforces that certain checks pass at each commit.
|
=> Enforces that certain checks pass at each commit.
|
||||||
|
=> https://pre-commit.com/
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
./run.py
|
./run.py
|
||||||
|
@ -74,40 +84,41 @@ def action_help() -> None:
|
||||||
|
|
||||||
Options, Run Locally:
|
Options, Run Locally:
|
||||||
./run.py app
|
./run.py app
|
||||||
=> Will run the app on port 8787, for local development.
|
=> Will run the app live on port 8787.
|
||||||
|
|
||||||
Options, Check:
|
Options, Check:
|
||||||
./run.py check
|
./run.py check
|
||||||
=> Will run all checks, including static analysis and tests.
|
=> Will run all checks, including static analysis and tests.
|
||||||
|
|
||||||
./run.py analyze-quality [OPTIONS]
|
./run.py analyze-quality [OPTIONS]
|
||||||
=> Will run the static code-quality analysis suite.
|
=> Not yet implemented...
|
||||||
=> OPTIONS will be passed directly to the tool (ruff).
|
=> Potentially, could run ruff on Python snippets in the book.
|
||||||
|
|
||||||
./run.py analyze-types [OPTIONS]
|
./run.py analyze-types [OPTIONS]
|
||||||
=> Will run the static type checking suite.
|
=> Not yet implemented...
|
||||||
=> OPTIONS will be passed directly to the tool (mypy).
|
=> Potentially, could run mypy on Python snippets in the book.
|
||||||
|
|
||||||
./run.py analyze-security
|
./run.py analyze-security
|
||||||
=> Will run the static security analysis suite.
|
=> Will run the static security analysis suite.
|
||||||
|
|
||||||
./run.py analyze-format [--overwrite] [OPTIONS]
|
./run.py analyze-format [--overwrite] [OPTIONS]
|
||||||
=> Will run the code formatter in read-only omde.
|
=> Not yet implemented...
|
||||||
=> '--overwrite' will cause the formater to reformat all files.
|
=> Potentially, could format Python snippets in the book.
|
||||||
=> OPTIONS will be passed directly to the tool (tan).
|
|
||||||
|
|
||||||
./run.py test
|
./run.py test
|
||||||
|
=> Not yet impelmented...
|
||||||
|
=> Potentially, would test distro commands in an appropriate container.
|
||||||
|
=> Potentially, would turn Python snippets into pytest units.
|
||||||
|
- See https://github.com/modal-labs/pytest-markdown-docs
|
||||||
=> Will run all Markdown Python snippets as tests.
|
=> Will run all Markdown Python snippets as tests.
|
||||||
|
|
||||||
Options, Build & Deploy:
|
Options, Build & Deploy:
|
||||||
./run.py build
|
./run.py build
|
||||||
=> Will build, tag and upload a docker image appropriately.
|
=> Will build a docker image, and tag it :dev.
|
||||||
|
|
||||||
./run.py build-release
|
|
||||||
=> Will build, tag and upload a docker image appropriate for release.
|
|
||||||
|
|
||||||
Options, Housekeeping:
|
Options, Housekeeping:
|
||||||
./run.py clean
|
./run.py clean
|
||||||
|
=> Not yet implemented...
|
||||||
=> Will delete all data caused by this project's presence on your system.
|
=> Will delete all data caused by this project's presence on your system.
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
@ -161,15 +172,13 @@ def action_publish() -> None:
|
||||||
subprocess.run([
|
subprocess.run([
|
||||||
"podman", "login", REGISTRY_HOST,
|
"podman", "login", REGISTRY_HOST,
|
||||||
"--username", REGISTRY_USER,
|
"--username", REGISTRY_USER,
|
||||||
"--password", REGISTRY_PASSWORD,
|
"--password", REGISTRY_PASSWORD(),
|
||||||
])
|
])
|
||||||
|
|
||||||
## TODO: Ensure git tag matches.
|
|
||||||
|
|
||||||
# Tag & Publish Image @ :<commit_id>
|
# Tag & Publish Image @ :<commit_id>
|
||||||
subprocess.run([
|
subprocess.run([
|
||||||
"podman", "image", "push",
|
"podman", "image", "push",
|
||||||
f"{IMAGE_NAME}:dev",
|
f"{IMAGE_NAME}:{get_git_revision_hash()}",
|
||||||
f"{REGISTRY_HOST}/{REGISTRY_USER}/{IMAGE_NAME}:{get_git_revision_hash()}",
|
f"{REGISTRY_HOST}/{REGISTRY_USER}/{IMAGE_NAME}:{get_git_revision_hash()}",
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -182,7 +191,7 @@ def action_publish() -> None:
|
||||||
# Tag Image
|
# Tag Image
|
||||||
subprocess.run([
|
subprocess.run([
|
||||||
"podman", "tag",
|
"podman", "tag",
|
||||||
f"{IMAGE_NAME}:dev",
|
f"{IMAGE_NAME}:{get_git_revision_hash()}",
|
||||||
image_tag
|
image_tag
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -206,6 +215,22 @@ def action_app() -> None:
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
####################
|
||||||
|
# - Actions - Analyze
|
||||||
|
####################
|
||||||
|
def action_analyze_security() -> None:
|
||||||
|
Path('.cache-trivy').mkdir(parents=True, exist_ok=True)
|
||||||
|
subprocess.run([
|
||||||
|
"podman", "run", "--rm", "-it",
|
||||||
|
"--workdir", "/src",
|
||||||
|
"--volume", ".:/src",
|
||||||
|
"--volume", "./.cache-trivy:/root/.cache",
|
||||||
|
"ghcr.io/aquasecurity/trivy:latest",
|
||||||
|
"fs", "--quiet", "--scanners", "vuln,secret,config,license",
|
||||||
|
"--exit-code", "1", "./"
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
@ -215,7 +240,7 @@ if __name__ == "__main__":
|
||||||
# Check Available Commands
|
# Check Available Commands
|
||||||
for cmd in CMD_DEPENDENCIES:
|
for cmd in CMD_DEPENDENCIES:
|
||||||
if not cmd_exists(cmd) :
|
if not cmd_exists(cmd) :
|
||||||
print("One or more dependencies are not installed. Please see --help.")
|
print(f"{cmd} is not installed. Please see --help for instructions.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
with cd_script_dir():
|
with cd_script_dir():
|
||||||
|
@ -227,6 +252,8 @@ if __name__ == "__main__":
|
||||||
"app": action_app,
|
"app": action_app,
|
||||||
"dev": lambda: print("TBD"),
|
"dev": lambda: print("TBD"),
|
||||||
|
|
||||||
|
"analyze-security": action_analyze_security,
|
||||||
|
|
||||||
"help": action_help,
|
"help": action_help,
|
||||||
"-h": action_help,
|
"-h": action_help,
|
||||||
"--help": action_help,
|
"--help": action_help,
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
# For git noobsies
|
||||||
|
Start by reading: http://rogerdudler.github.io/git-guide/.
|
||||||
|
|
||||||
|
This is also not meant to be an in depth introduction to git. It should, however, be enough to get you working. Also, it assumes you have a working git installation.
|
||||||
|
|
||||||
|
To **configure** git:
|
||||||
|
1. `git config --global user.name <name>` where `<name>` is your git (or GitHub) username.
|
||||||
|
2. `git config --global user.email <email>` where `<name>` is your git (or GitHub) email.
|
||||||
|
3. Confirm that the information is correct with `git config --global --list`.
|
||||||
|
|
||||||
|
To **clone** (download) this repository:
|
||||||
|
1. Move to the desired directory and write `git clone https://github.com/volesen/DiscreteMath.git <dir>` where `<dir>` is the name of the directory to place it in.
|
||||||
|
|
||||||
|
To **pull** (update your local repository) from origin:
|
||||||
|
1. `git pull`.
|
||||||
|
2. Done. If this fails, it's probably because you've changed or removed some files others have also changed or removed.
|
||||||
|
|
||||||
|
To create a **branch**:
|
||||||
|
1. Create an issue using the web GUI. From here on `<id>` will refer to the id of the issue. For example 14.
|
||||||
|
1. Create a new branch `git checkout -b <name>` where `<name>` is `<id>-issue`. This also moves your HEAD to the new branch.
|
||||||
|
|
||||||
|
To **push** (upload) your changes to the current branch:
|
||||||
|
1. Before anything else, make sure to pull the current branch with `git pull`. This helps in dealing with merge conflicts
|
||||||
|
2. `git add .` to add all your changed, deleted and added files to the "staging area".
|
||||||
|
3. `git commit -m "<message>"` to create a "commit" with all your changes. This only changes things in your local repository. <message> should be a short description of what your commit changes. [A great guide to writing good messages](https://chris.beams.io/posts/git-commit/).
|
||||||
|
4. `git push` to push your newly created commit to the branch. This is the first time any changes are made outside of your computer. [branch](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging). If it is a new branch write `git push --set-upstream origin <name>` where `<name>` is the name of the branch.
|
||||||
|
5. Aaand your done.
|
||||||
|
|
||||||
|
To **swap** branch (if you want to work at multiple branches simultaneously):
|
||||||
|
1. `git checkout <name>` where `<name>` is the name of the branch.
|
||||||
|
|
||||||
|
To **delete** a branch:
|
||||||
|
1. To delete a local branch write `git branch -d <name>` where `<name>` is the name of the branch.
|
||||||
|
1. To delete a remote branch (be careful!) write `git push origin --delete <name>` where <name> is the name of the branch.
|
||||||
|
|
||||||
|
To **move** or delete files without breaking git:
|
||||||
|
1. To move a file that's tracked by git without breaking things, use `git mv <source> <dest>`.
|
||||||
|
2. To delete a file that's tracked by git, use `git rm <to_delete>`.
|
||||||
|
|
||||||
|
In general it is better to commit as often as possible. Make sure what you have works and doesn't break anything else, and then commit that shit. Doesn't matter if it's a single line or a corrected punctuation mark in a comment. Commits are not precious. That way you never change too many files at a time or give others the time to do the same, reducing the need to merge files. It also makes it easier to write good commit messages :)
|
||||||
|
|
||||||
|
### Rebasing and Why You Need It
|
||||||
|
Imagine the following situation:
|
||||||
|
- You start a branch `feature` from some commit on `master`; let's call this commit 0a.
|
||||||
|
- You make 3 commits to feature: 1b, 2b, and 3b.
|
||||||
|
- Meanwhile, 5 new commits are made on master: 1a, 2a, 3a, 4a, 5a.
|
||||||
|
- It comes time to merge feature with master. But there's a problem:
|
||||||
|
You worked from 0a, thus you can't `git merge` with master, which is at 5a.
|
||||||
|
- What to do?
|
||||||
|
|
||||||
|
Right now your feature branch looks like this: 0a -> 1b -> 2b -> 3b.
|
||||||
|
|
||||||
|
You need it to look like this: 0a -> **1a -> 2a -> 3a -> 4a -> 5a** -> 1b -> 2b -> 3b.
|
||||||
|
|
||||||
|
To make this reality, you can use the *magic of rebasing*!
|
||||||
|
1. Checkout your branch: `git checkout feature`.
|
||||||
|
2. Hit git log. It looks like 0a -> 1b -> 2b -> 3b.
|
||||||
|
2. *Rebase* from master: `git rebase master`.
|
||||||
|
4. Hit git log. It now looks like 0a -> **1a -> 2a -> 3a -> 4a -> 5a** -> 1b -> 2b -> 3b.
|
||||||
|
5. You've *changed history*. Now, if you were to go `git checkout master` and `git merge feature`, everything will work!
|
||||||
|
|
||||||
|
You'll notice a **problem**: Because of the changed history, you can no longer push to the remote branch. This can be fixed in two ways:
|
||||||
|
* If you're an asshole: `git push --force`. You'll overwrite the entire remote branch with your local one. **CAREFUL!**
|
||||||
|
* If you can live with a merge commit: `git pull feature`. You'll create a merge commit, combining the rebased and unrebased versions, after which `git push` will work flawlessly.
|
||||||
|
|
||||||
|
Also, a PSA: Delete your branches when they're merged!
|
Loading…
Reference in New Issue