ttc-cases / pydevx-lindjacob

1 stars 0 forks source link

Customize your devcontainer #2

Closed github-actions[bot] closed 2 months ago

github-actions[bot] commented 2 months ago

[!NOTE] ☝️ Learning goals in this issue

  • add extensions to VS Code and add them to your devcontainer
  • add a .gitignore file to your repo
  • use the devcontainer's postCreateCommand feature to run a customized shell script
  • configure git to use a shared .gitconfig file
  • use the Problems tab to highlight and fix issues

🏋️‍♀️ Exercise

  • [x] 👉 Add some favorite extensions to VS Code 👈
  • [x] 👉 Add extension to the devcontainer so they become shared among all team members 👈
  • [x] 👉 Sync extension so they become your personal favorites - but not shared 👈

First let's install a handful of really useful extensions. Find and install all of the following (some of them may already be installed, in that case just verify that they are installed):

All-right enough for now. You can explore all of these extensions on your own hand, for now just pay attention to autopep8 - the auto formatter. In the documentation to the extension it instructs you how to enabled it in your settings.json file:

  "[python]": {
    "editor.defaultFormatter": "ms-python.autopep8",
    "editor.formatOnSave": true
  }

Set that up.

Lets take everything that's Python related (Python, Pylance, Python Debugger and autopep8) add it to the devcontainer - simple right-click on the extension and from the context menu choose add to devcontainer.json. We do this because we want every team member to have the same off-set condition when we collaborate.

Some of these extension are more convenient tahn strictly necessary, but they only work in containerized environments if they are installed inside the container. That's true for Phind and Git Graph so add them too, in the same way.

In you .devcontainer/devcontainer.json file you end op with a customizations section something like this:

    "customizations": {
        "vscode": {
            "extensions": [
                "phind.phind",
                "mhutchie.git-graph",
                "ms-python.python",
                "ms-python.vscode-pylance",
                "ms-python.autopep8",
                "ms-python.debugpy"
            ]
        }
    },

Rebuild your container and see that it works.

As before run git add, commit and push. Remember to mention the Issue number in the commit message.

For the remainder of the extensions (GitHub Copilot, GitHub Copilot Chat and GitHub Pull Requests) they are also merely convenient and not strictly required, so you can and them by syncing them with your user:

Right-click on each of them, one at a time, but instead of adding them to the container you mark Sync This Extension - provided that you are logged into VS Code.

🏋️‍♀️ Exercise

  • [x] 👉 Add a .gitignore file 👈
  • [x] 👉 Use a development branch to do it 👈

Different languages and technologies creates different output's from builds, temp files, caches etc. Theses files are referred to as derived objects and they are seldom considered configuration objects meaning they should not be version controlled - at least not in git.

This is why your project needs a .gitignore file - which specifically tells git which files to ignore.

But before you continue with creating the .gitignore file, setup a development branch dedicated to this issue #2 and commit the changes we have done so far.

Hint on how to create a branch dedicated to an issue You have at least three obvious ways to do this - here are som pointers: - [Use the Git Pull Request extension in VS Code](https://code.visualstudio.com/blogs/2020/05/06/github-issues-integration#_working-on-issues). - [Do it from the issue on the GitHub web](https://docs.github.com/en/issues/tracking-your-work-with-issues/creating-a-branch-for-an-issue) - [Do it from the command line using the `gh issue develop` CLI](https://cli.github.com/manual/gh_issue_develop)

The GitHub community jointly maintains these .gitignore files for each specific language and technology. Have a look at the github/gitignore repo and see if you can finde something useful in context of Python.

Create a file in the root of your repo named .gitignore. copy and paste the raw content of the file you found into it.

Spoiler [`Python.gitignore`](https://github.com/github/gitignore/blob/main/Python.gitignore) You can see the file in it's _raw_ mode and copy the content from there using clip board, or you can simply copy it over from it's location on git and into your repo by running this command in your terminal to download it: ```shell curl -L https://raw.githubusercontent.com/github/gitignore/main/Python.gitignore >.gitignore ```

Then git add, commit remember a clever commit message - you can leave out the push until we're all done with this issue.

🏋️‍♀️ Exercise

  • [x] 👉 Add and install a shared .gitconfig file 👈

You have already come very far on your DevX setup, but let's add just one more nice feature:

Create a .gitconfig file in the root of your repository and copy the following context into it:

[push]
  default = current 

[alias]
  undo-commit = reset --soft HEAD^
  redo-commit = commit -C HEAD --amend 
  addremove = add -A
  co = checkout
  st = status
  root = rev-parse --show-toplevel
  tree = log --graph --full-history --all --color --date=short --pretty=format:\"%Cred%x09%h %Creset%ad%Cblue%d %Creset %s %C(bold)(%an)%Creset\"

The file represents some specific git settings - we can always add more, for now we just want to mimic that that we're working in a team, and we would like the team to jointly adhere to the same how-we-work standard. and that incudes that we're using git in the same way.

To get this into play, let's ask the devcontainer to add it as part of the postCreateCommand

The postCreateCommand in the devcontainer.json file is designed to only tun one command. So a convention is simply to have it runt a postCreateCommand.sh script - and then add whatever you need to that script.

Let's first create a script

.devcontainer/postcreate.sh

Like this:

#!/bin/env bash

git config --global --add safe.directory "$(git rev-parse --show-toplevel)"
git config --local --get include.path | grep -e ../.gitconfig || git config --local --add include.path ../.gitconfig

To make the script executable we will need to set the execution bit. From the terminal run:

chmod +x .devcontainer/postCreate.sh

Last change we need is in the is in the .devcontainer/devcontainer.json file itself.

You will probably find a line that is commented out, which starts with "postCreateCommand":...

Change that line to read

    // Use 'postCreateCommand' to run commands after the container is created.
    "postCreateCommand": "$(git rev-parse --show-toplevel)/.devcontainer/postcreate.sh"

[!TIP] json is very sensitive to misplaced commas. If there are any definitions after postCreateCommand then the line will need a comma in the end. ...and The features list was the last definition, but now it's not, so now that needs a comma in the end. Pay attention the the "Problems" tab in the lower panel - that is your friend!

Done! do your final git add, commit again - remeber a clever commit message and leave out the push for now.

🏋️‍♀️ Exercise

  • [x] 👉 Examine your development branch with Git Graph 👈
  • [x] 👉 Deliver your changes back to main (you have options) 👈

Now you have a branch - related to a specific issue - that has more than one commit. Consider your options:

There's no right or wrong all choices to these different options are valid and common. Make a choice - and argue your case.

lindjacob commented 2 months ago

Discussion on my choices

  1. Push the branch to origin and create a pull request (PR)

    • Reasoning: This allows collaboration. Other team members can review the changes, provide feedback, and ensure that the code meets the project's standards before it is merged into the main branch.
    • Reviewing the PR Ideally, a team member or a designated reviewer (senior dev) should accept the PR. This ensures that at least one other person has reviewed the changes and agrees that they are ready to be merged.
  2. Should you rebase first?

    • Reasoning: Yes, in this case I would rebase my branch onto the latest main branch before creating the PR. If needed I would interactively rebase, to squash irrelevant commits. This ensures that my branch is up-to-date with the latest changes from the main branch while keeping a cleaner (linear) project history and ensures the later merge with fast-forward. If the branch I was working on was public, I would NOT use rebase, as it would make Git think that my main branch has diverged from everybody else's. I would then have to merge the two branches back together which would create two sets of commits that contain the same changes.
  3. Should you squash the commits on the branch into just one on main?

    • Reasoning: No not in this case. If I use squash the commits, we will lose the advantage of rebasing. If I was merging a hotfix, I might have squashed the commits to keep the main branch history clean and concise. However, if I was reviewing someone else's PR and some of the commits have no relevance I might want to interactively rebase and fixup those commits or squash the commits altogether - For this case, the argument can be made, that the commits are so small, that they could be squashed, but I wanted to discuss the idea.
  4. When the changes have arrived on main, should you then delete the development branch?

    • Reasoning: Yes, I would delete the development branch both in the local repository and in origin. This helps keep the repository clean and avoids clutter from old branches, which avoids confusion and ensures that everyone is working with the correct code.