git branching model

git

git is a tool for the command line to backup and distribute source code. There are multiple beautifully made webpages and GUI tools which help to use it and to make sense out even out of the biggest code bases.

The workflow is simple: Each code base / each project is in its own repository. As soon as you’ve finished a change or a feature you commit (save) your code. You can switch back and forth between commits and can compare the changes you’ve made. If you want to share or backup your repository, you push (upload) it to a git hoster. Other participants in your project can pull (download) your repository, including all commits you’ve made. One repository can have multiple branches (versions of your code), each of those has its own commits. Branches can be merged (united) and created.

As a hoster for git I can recommend github which is perfect for open source projects, and gitlab if you need a lot of private repositories. Both services are free, at the time of writing github has some more useful features (like project management with Kanban) compared to gitlab, but both services do a very good job with hosting and helping you make sense out of large repositories.

As committing, pulling, pushing may be complicated for new users I recommend a GUI application to do those steps for you, until you feel confident to use the command line. One of the best is gitkraken, github even provides its own desktop client.

Git is very handy as a backup tool, but it can also help you to structure different versions of your code, allows you to do code reviews and to allow statistics about the overall progress of the repository.

Branching may be confusing for new users, but if integrated in your workflow in a sensible way it is a very handy tool to allow work on different features and versions of your software in a sensible way. How to name and organize your branches is explained very well in a tutorial on the webpage from atlassian.
Another very well written (but a bit more technical) post to branching concepts can be found on the blog of nvie

continuous integration

In the following article I will use continuous integration for quality control: I want to make sure my projects are building and their unit tests are passing. I’ve configured CI in a project of mine for both the C# and the php part. Here’s how:

C#

I’m using appveyor for this. Its as easy as going to their webpage, and adding your project from github. It will automatically figure out what and how to build. You can customize the actions appveyor executes with an appveyor.yml file in your project root. In the following example I customized appveyor to work with codecov.io to get code coverage of the unit tests:

os: Visual Studio 2017
install:
- set PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH%
before_build:
  - nuget restore
build:
  project: Famoser.SyncApi.sln
  verbosity: minimal
test_script: 
    - .\packages\OpenCover.4.6.519\tools\OpenCover.Console.exe -register:user -target:"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\MSTest.exe" -targetargs:"/noresults /noisolation /testcontainer:"".\Famoser.SyncApi.UnitTests\bin\Debug\Famoser.SyncApi.UnitTests.dll" -filter:"+[Famoser.SyncApi]*  -[Famoser.SyncApi]Famoser.SyncApi.Properties.*" -excludebyattribute:*.ExcludeFromCodeCoverage* -hideskipped:All -output:.\SyncApi_coverage.xml -returntargetcode
    - "SET PATH=C:\\Python34;C:\\Python34\\Scripts;%PATH%"
    - pip install codecov
    - codecov -f "SyncApi_coverage.xml"  
# preserve "packages" directory in the root of build folder but will reset it if packages.config is modified
cache:
  - packages -> **\packages.config

php

I’m using travis-ci.org to build & test my application, and codeclimate to check my coding style. As usual with web projects, it needs a little more configuration to get up and running.

codeclimate
For this service, you register your project on the webpage of codeclimate, and create a config file named codeclimate.yml. In it, you must specify the paths of your php files, and the engines you want to look at your code. A ready to use config file may look like this:

engines:
  fixme:
    enabled: true
  phpcodesniffer:
    enabled: true
  phpmd:
    enabled: true  
  duplication:
    enabled: true
    config:
      languages:
      - php
ratings:
  paths: ["Famoser.SyncApi.Webpage/src/**/*"]
exclude_paths: ["Famoser.SyncApi.Webpage/src/public/assets/**/*"]

travis
First, you add a config file called .travis.yml. You need to specify the language and the versions of the language to use for testing. You can also specify scripts which run before / after various events. After the configuration is done, add the project on travis-ci.org.

For my setup with code climate & composer I need some additional config: I need to install composer dependencies and execute a script to push test results to codeclimate. For the connection with codeclimate to work be sure to include

  • an environment variable on travis-ci.org (under travis-ci -> settings) with key CODECLIMATE_REPO_TOKEN and value your_test_reporter_token (you may find this token on codeclimate -> settings -> Test Coverage).
  • a new composer dependency under require-dev: "codeclimate/php-test-reporter": "dev-master"
  • the after_script part in the .travis-yml as specified below.

a ready to use configuration may look like this:

language: php
php:
    - 7.0
    - 7.1
install:
    - cd Famoser.SyncApi.Webpage
    - composer install --dev
after_script:
- ./vendor/bin/test-reporter

For the automatic execution of phpunit tests, configure phpunit. A sample configuration file looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php" stopOnFailure="false">
    <testsuites>
        <!-- following specifies to executes all files in the tests directory which end in Test.php, for example SimpleTest.php -->
        <testsuite name="Application Test Suite">
            <directory suffix="Test.php">./tests</directory>
        </testsuite>
    </testsuites>
    <php>
        <!-- specify php environment values -->
        <!-- <env name="TESTING_MODE" value="testing"/>-->
    </php>
    <logging>
        <!-- this is important for the code climate connection -->
        <log type="coverage-clover" target="build/logs/clover.xml"/>
    </logging>
    <filter>
        <!-- whitelist all php source files you may use in the process of building & testing -->
        <whitelist>
            <directory suffix=".php">src</directory>
        </whitelist>
    </filter>
</phpunit>

For other services providing CI look up Jenkins and docker

set up symfony

Prerequisites

  • installed XAMPP or MAMP (apache server & php installation bundles)
  • installed composer (php libraries)
  • installed npm (deploy libraries)

Step 1: install Symfony installer

option 1 (recommended): download the installer, and move it to the directory where your repository should be located

php -r "readfile('https://symfony.com/installer');" &gt; symfony
move symfony D:\Repos
php symfony new my_project

option 2: create the project with composer:

composer create-project symfony/framework-standard-edition my_project

follow the instructions in the console (you will probably need to configure your database & mail settings)

now, update all packages with composer:

composer update

Step 2: set up npm

create a file named package.json, adapt following json to your needs:

{
  "name": "my_project",
  "version": "0.1.0",
  "description": "My Project",
  "repository": {
    "type": "git",
    "url": "git://github.com/famoser/my_project.git"
  },
  "keywords": [
    "office",
	"online"
  ],
  "author": "Florian Moser &lt;git@famoser.ch&gt;",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/famoser/my_project/issues"
  },
  "homepage": "https://github.com/famoser/my_project",
  "devDependencies": {
    "bower": "^1",
    "browser-sync": "^2",
    "del": "^2",
    "gulp": "^3",
    "gulp-all": "^1",
    "gulp-batch": "^1",
    "gulp-bower": "^0",
    "gulp-clean-css": "^2",
    "gulp-concat": "^2",
    "gulp-less": "^3",
    "gulp-notify": "^2",
    "gulp-rename": "^1",
    "gulp-sass": "^2",
    "gulp-sourcemaps": "^1",
    "gulp-uglify": "^1",
    "gulp-watch": "^4",
    "less-plugin-autoprefix": "^1",
    "rimraf": "^2"
  }
}

run in your console

npm update

Step 3: set up bower

create a file named bower.json, adapt following json to your needs:

{
  "name": "my-project",
  "version": 0.1,
  "homepage": "https://github.com/famoser/my-project",
  "authors": [
    "famoser &lt;git@famoser.ch&gt;"
  ],
  "description": "My Project",
  "keywords": [
    "php"
  ],
  "license": "MIT",
  "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "test",
    "tests"
  ],
  "dependencies": {
    "jquery": "2.2.3",
    "bootstrap": "3.3.6",
    "components-font-awesome": "*"
  }
}

create a file named .bowerrc, with following json content:

{
    "directory": "web/assets/vendor/"
}

to create such a strange filename you can run

copy NUL > .bowerrc

in your console.

Step 4: set up build tools

I’ll use gulp for this.
Create a file named guldfile.js, content must be JavaScript. You’ll find a good starting point here: gist. There is quite a lot going on in this file, the instructions and the configuration is at the top.

Now run in your console

gulp

to build all frontend libraries for the first time.

Step 5: set up source control

  • add a README.MD describing your project
  • add a LICENSE.MD so other users may or may not be allowed to use your work (I’m recommending the MIT license)
  • exclude unnecessary files from git (bower, composer & IDE files)
.idea
node_modules
/web/assets/vendor
symfony-scripts/.git

Step 6: rename your AppBundle

choose a custom name for your application, make it VendorApplicationBundle, so for example GoogleYoutubeBundle.
Files / Folder you need to adapt:

  • The file /src/AppBundle/AppBundle.php
  • The namespaces in all .php files inside /src/AppBundle/**/*.php
  • The folder /src/AppBundle
  • in /app/AppKernel.php you need to register your renamed bundle (just replace the old AppBundle/AppBundle entry)
composer

composer

Composer is a dependency manager for php. It also automatically generates all code necessary for autoloading.

The setup is simple:

place a composer.json in your project folder

{
  "name": "username/repo",
  "type": "framework",
  "license": "MIT",
  "description": "A project which gets things done",
  "keywords": [
    "project keywords", "another keyword"
  ],
  "authors": [
    {
      "name": "Florian Moser",
      "email": "me@myurl.ch",
      "homepage": "http://myurl.ch",
      "role": "Developer"
    }
  ],
  "require": {
    "php": ">=7.0",
    "phpmailer/phpmailer": "5.2.*",
    "famoser/minify": "dev-master"
  },
  "autoload": {
    "psr-4": {
      "username\\myproject\\": "src/"
    }
  },
  "minimum-stability": "dev"
}

Specifiy all packages  you need in the require node.
In the autoload node, define the standard you’re using, your vendor & project prefix, and the folder the source is located.

Let composer do its magic

composer install

This will download / actualize all dependencies specified in the require node (if applicable). Those files will be placed in a vendor folder. Inside this folder, there is a file named autoload.php. This file contains code to autoload all dependecies and additional sources specified in the autoload node. So all you need to do to use the dependencies is to include this autoload.php in your project.

Some other useful commands

composer update

When first running composer install, composer generates a composer.lock file, to ensure everyone executing composer install installs the same versions of the dependencies. composer update deletes this .lock file, and resolves the dependencies again.

You can download the tool from here.

Bower

bower

Bower is a package manager which comes in handy for web frontend frameworks like foundation, bootstrap, jquerysemantic ui, …

Setup is simple:

Place a bower.json in your project root

{
  "name": "project-name",
  "version": 0.1,
  "homepage": "https://url.com/username/repo",
  "authors": [
    "famoser <me@myurl.ch>"
  ],
  "description": "A project which gets things done",
  "keywords": [
    "project keywords", "another keyword"
  ],
  "license": "MIT",
  "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "test",
    "tests"
  ],
  "dependencies": {
    "jquery": "2.2.*",
    "semantic-ui": "*"
  }
}

Let bower do its magic

bower install

This will download / actualize all dependencies specified in the dependencies node.

You may download the tool, after you have set up npm, simply by executing

npm install bower --save-dev

in your console.

npm

npm

The Node Package Manager is a command line javascript package manager. It is powerful if you use build tools like gulp or if you develop server side with javascript.

The setup is simple:

place a package.json in your project folder

{
  "name": "project-name",
  "version": "0.1.0",
  "description": "project-name is a project which gets things done!",
  "repository": {
    "type": "git",
    "url": "git://url.com/username/repo.git"
  },
  "keywords": [
    "project keywords", "another keyword"
  ],
  "author": "Florian Moser <me@myurl.ch>",
  "license": "MIT",
  "bugs": {
    "url": "https://url.com/username/repo/issues"
  },
  "homepage": "https://url.com/username/repo",
  "devDependencies": {
    "gulp": "^3.9.1"
  }
}

Let npm do its magic

npm install

This will download / actualize all dependencies specified in the devDependencies or dependencies node.

Some other useful commands

npm install <package_name>

Install the package into the current directory. Append the flag --save or --save-dev to put the package into your dependencies.

You can download the tool from here.

scrum

Scrum ist ein agiler Entwicklungsprozess. Er setzt den Schwerpunkt auf direkte Kommunikation, ermöglich aber trotzdem gute Planung und Dokumentation.

Er setzt das Agile Manifesto um:

  • Individuen und Interaktionen haben Vorrang vor Prozessen und Werkzeugen
  • Funktionsfähige Produkte haben Vorrang vor ausgedehnter Dokumentation
  • Zusammenarbeit mit dem Kunden haben Vorrang vor Vertragsverhandlungen
  • Eingehen auf Änderungen haben Vorrang vor strikter Planverfolgung

Um dies zu erreichen werden zuerst alle Beteiligten in zwei Gruppen aufgeteilt: pigs & chickens.
So sind die pigs die, die unmittelbar zum Erfolg des Produktes beitragen (wie zum Beispiel die Programmierer), alle anderen sind Chickens (wie zum Beispiel die Geschäftsleitung).

Die Gruppenzuordnung bestimmt, wie häufig die entsprechende Person in den Entwicklungsprozess eingreiffen darf. So stehen die Pigs täglich untereinander im Austausch, die Chickens besprechen ihre Anliegen lediglich mit einer Ansprechsperson der Pigs.

pigs

Die pigs sind ein Team von bis maximal 10 Personen. Darin enthalten sind alle Experten, die zur Programmentwicklung benötigt werden.

Sie tauschen sich täglich untereinander über die Projektsfortschritte aus, und sind alle gleichberechtigt, verteilen die Aufgaben untereinander und helfen sich bei auftretenden Problemen. Das Team trägt gemeinsam die Verantwortung für den Projekterfolg.

Zwei Mitglieder des Teams haben zusätzlich spezielle Aufgaben (sie bleiben aber trotzdem gleichberechtigt):

  • der Scrum Master ist der Moderator der Meetings. Er ist damit dafür verantwortlich, dass der Scrum Prozess korrekt ausgeführt wird, und dass alle Impediments (Störfaktoren), die die Teameffizienz beeinträchtigen, aus der Welt geschafft werden.
  • der Produkt Owner priorisiert und bewertet die Arbeit des Teams, er ist die Ansprechsperson falls Fragen betreffend der konkreten Gestaltung des Programmes auftreten. Er geniesst sowohl das Vertrauen des Arbeitgebers als auch das des Teams.

Die Planung

Anforderungen des Projektes werden mittels User Stories und Use Cases formuliert.
User Stories: Als <USER> möchte ich zum
Use Cases: Der <USER> möchte <RESULTAT>

Die so erstellten Anforderungen werden im Product Backlog hinterlegt, und danach vom Arbeitsgeber evaluiert und priorisiert. Anhand dieser Vorgaben wird nun ein Sprint Backlog erstellt: die Vorgaben werden in individuelle Aufgaben unterteilt, deren Aufwand vom Team geschätzt wird.

Nun wird anhand der Entwicklungsgeschwindigkeit des Teams ein Project-Burndown Chart auf Iteration und Release Ebene erstellt.
Die Entwicklung kann beginnen.

Der Sprint

Ein Sprint ist etwa 30 Tage lang. Er ist ein in sich abgeschlossener Prozess an dessen Anfang die Planung des Sprints steht. Während dem Sprint selber werden die konkreten Aufgaben umgesetzt. Am Schluss jedes Sprintes ist eine funktionierende, in sich abgeschlossene Version des Programmes verfügbar.

Planung eines Sprints

Die derzeit wichtigsten Aufgaben werden ausgewählt, und es wird ein Sprint geplant, sodass alle ausgewählten Aufgaben fertig werden.

Wenn die Planung abgeschlossen wurde, wird ein Sprintvertrag zwischen dem Team und dem Arbeitgeber unterzeichnet. Der Vertrag garantiert dem Team, das keine Änderungen an den Anforderungen während dem Sprint gemacht werden. Im Gegenzug garantiert das Team die Ausführung der im Vertrag enthaltenen Aufgaben.

Es wird nun ein Sprint Burndown Char erstellt, der die Sprint Anforderungen visualisiert. Die x Achse ist die Zeit, die y Achse zeigt der geschätzte Arbeitsaufwand der noch zu erledigenden Arbeiten. Gestartet wird bei (0, max(y))

Entwicklungsprozess

Jeden Tag findet ein Daily Scrum statt, ein kurzes Meeting des Teams (5-10min). Jeder schildert knapp, was er gestern gemacht hat und was er heute machen wird. Er meldet sich hier, falls er sich mit jemandem aus dem Team koordinieren muss, oder falls er Hilfe bei einem Problem braucht.

Bei grossen Programmen findet wöchentlich ein Weekly Scrum statt: Ein Delegierter vom Team geht an das sogenannte Scrum of Scrums. Er fasst dort die Ergnisse seines Scrums zusammen und koordiniert mit andern Scrums falls nötig. Bei sehr grossen Programmen kann es sogar ein Meta Scrum geben. Jedes Scrum of Scrums entsendet einen Delegierten, dann geschieht im Prinzip das selbe wie im Weekly Scrum, einfach im grösseren Rahmen.

Ende des Sprints

Nach dem Ende des Sprints ist der y-Wert auf dem Sprint BurndownChart auf 0.

Das Ergebnis des Sprints wird Product Increment genannt, und ist eine funktionierende Version des Programmes. Der umgesetzte Funktionsumfang ist in sich abgeschlossen, und der Product Owner könnte das Programm nun veröffentlichen.

Der vergangene Sprint wird nun vom Team analysiert, positive und negative Aspekte werden gesammelt. Der Scrum Master wertet die Ergebnisse aus, und unternimmt Änderungen am Workflow falls nötig.

Im Sprint Review schliesslich werden die Ergebnisse des Sprints vom Arbeitgeber abgenommen.

Ist das Programm noch nicht fertig, ist nun der Zeitpunkt, um mit der Planung des nächsten Sprints zu beginnen.

Diese Zusammenfassung wurde aus Material von ti8m erstellt, und durch eigene Erfahrungen ergänzt.

licenses

open source software should be distributed under licences. I’ve put together a short overview of the most important ones. and what they accomplish:

MIT: Do whatever you want with the code, but you cannot hold the author responsible for bugs

GNU GPL: Hardcore open-source: If you want to use a library which is licensed under GPL your application has to be open source too.

Creative Commons: A collection of licences, you can choose which flavour you want here. You might be able to guess from the name of the generated license what you can and what you can’t do.

l;drLegal comes in handy if you want to know more about other licences.

I recommend you use the MIT license: You basically do not restrict anyone from using my code, but will not face legal consequences of any kind if your code is broken.

But why should I care?

In your license you can specify how one may use your code (if commercially or not, if allowed to modify it etc).

If your project is open source and free, you probably won’t have any difficulties with licences. However, if you intend to sell it, or keep your code private, you need to review them carefully: Some licences may restrict using code in commercial or non open source projects.

Personally, I think it’s a waste of time clearing up legal issues to use already written code, rather than spending this time on developing. The reason I make all of my code open source is than others can reuse the code and do not need to write the exact same thing I’ve already did. I think this should generally be the focus of open source; reducing the workload of all programmers in general.

git

git hooks on windows

In $GIT_DIR/hooks/* (typically in <repository_root>/.git/hooks/*) you may place scripts, which execute as you perform specific git operations on your repository. For more info on how to name the hooks and when exactly they are executed, type in git help hooks in your console.

However, you are not able to use commands you know from .cmd and .bat files. Instead, place this in your hook (for example post-checkout):

cd ./.git/hooks
start post-merge.cmd

now post-merge.cmd (placed in the same folder as the hooks) is called and executed by the hook.