Category Archives: Software Development

This category contains all my posts about software development. Tutorials, solutions to problems I’ve met, interesting things I’ve stumbled over, code samples, stuff I don’t want to forget, et cetera.

Using SSH keys with BitBucket/GitHub on Windows

Couldn’t get this to work, but now it does, so… time for another “note to self”. 🙂

Prerequisites

  • Git, obviously…
  • PuTTY, with puttygen, plink and pageant, to be exact…

Setup

  1. Open puttygen.
  2. Load your private key, or generate a new one and save it.
  3. Copy your public key (“Public key for pasting …”) to BitBucket/GitHub/etc.
  4. Open pageant
  5. Load your private key.
  6. Check that the key authentication works by running e.g.
    plink -v git@bitbucket.org
    plink -v git@github.com
  7. Point the GIT_SSH environment variable to plink.exe.

Now, as long as pageant is running with your private key loaded, it should work to clone, pull, push, etc. to/from both private and public repos. E.g. git clone git@github.com:example/some-private-repo.git.

Key here, for me, was the GIT_SSH variable that so many blogs, StackOverflow answers and forum posts failed to mention… Without that set, the plink check did still work, but git clone did not. It just failed with an authentication error. With that variable set it now works perfectly. 🙄🙂👍

Sources: makandracards.com, vladmihalcea.com

Manual WAMP stack

For future reference…

PHP

  1. Download an x64 Thread Safe zip from php.net.
  2. Read the note about Visual C++ Redistributable in the sidebar of that download page, and install the one required for your version.
  3. Unzip somewhere and add to PATH.
  4. Pick a php.ini and adjust as necessary (enabled extensions, etc.).
  5. In particular, make sure the following is not commented out:
    extension_dir = "ext"
  6. Check that it works:
    php --version

Composer

  1. Download the Windows Installer from getcomposer.org.
  2. Run the installer..
  3. Check that it works:
    composer --version

Apache

  1. Download the Apache Win64 zip from apachelounge.com.
  2. Read the note about Visual C++ Redistributable above the downloads on that download page, and install the required one.
  3. Unzip somewhere and adjust httpd.conf as necessary (paths, enabled modules, etc.).
  4. Install as service:
    httpd.exe -k install
  5. Start the service.
  6. Check that it works:
    start http://localhost

Apache with PHP

  1. Add the following to httpd.conf.
    LoadModule php7_module C:/path/to/php/php7apache2_4.dll
    <IfModule php7_module>
        DirectoryIndex index.html index.php
        AddHandler application/x-httpd-php .php
        PHPIniDir "C:/path/to/php"
    </IfModule>
  2. Add an index.php to your DocumentRoot for testing, e.g.:
    <?php phpinfo();
  3. Restart the Apache service.
  4. Check that it works:
    start http://localhost

MariaDB

  1. Download a Windows x86_64 MSI Package via mariadb.org.
  2. Run the installer.
  3. Optionally add some of the following to my.ini under mysqld section:
    ; Only listen on localhost
    bind-address=127.0.0.1

    ; Enable logging of queries

    ; (probably bad in production, but very helpful for development debugging)
    general-log=1
    general-log-file=queries.log
    log-output=file
  4. Restart the service, if you changed anything in the ini.
  5. Check that it works by connecting with HeidiSQL or any other SQL client.

Setting up GPG signing for Git/GitHub on Windows

What I did to get from working GPG to green and verified signatures for Git commits and tags on GitHub.

  1. Find the long id of the Signing key we want to use:
    🔶 $ gpg --edit-key alice
    gpg (GnuPG) 2.0.30; Copyright (C) 2015 Free Software Foundation, Inc.
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.

    Secret key is available.

    pub  4096R/AA79CCAE  created: 2017-08-23  expires: never       usage: SC
                         trust: ultimate      validity: ultimate
    sub  4096R/62275E24  created: 2017-08-23  expires: never       usage: S 👈
    sub  4096R/4AEA9524  created: 2017-08-23  expires: never       usage: E
    [ultimate] (1). Alice Person (alice) <alice.person@example.com>
    [ultimate] (2)  Alice Person (alice) <alice@example.org>

    🔶 gpg> quit

    🔶 $ gpg --list-secret-keys --keyid-format LONG alice
    sec   4096R/8C0BBECBAA79CCAE 2017-08-23
    uid                          Alice Person (alice) <alice.person@example.com>
    uid                          Alice Person (alice) <alice@example.org>
    ssb   4096R/6ADB9D4262275E24 2017-08-23 👈
    ssb   4096R/33F2E1644AEA9524 2017-08-23

    Note: So in this case we want 6ADB9D4262275E24

  2. Configure git and (optionally) make it sign all commits by default:
    🔷 $ git config --global user.name "Alice Person"
    🔷 $ git config --global user.email "alice.person@example.com"
    🔶 $ git config --global user.signingkey "6ADB9D4262275E24"
    🔷 $ git config --global commit.gpgsign true
    🔷 $ git config --global push.gpgsign if-asked
    🔶 $ where gpg
    C:\Program Files (x86)\GNU\GnuPG\pub\gpg.exe
    🔶 $ git config --global gpg.program "C:/Program Files (x86)/GNU/GnuPG/pub/gpg.exe"

    Note: If repo specific, just skip --global and run the command in the repo instead.

Test it…

  1. Do a commit:
    🔷 $ git init gpg-test
    🔷 $ cd gpg-test
    🔷 $ touch file.txt
    🔶 $ git commit -a -m "Signed commit"

    You need a passphrase to unlock the secret key for
    user: "Alice Person (alice) <alice.person@example.com>"
    4096-bit RSA key, ID 62275E24, created 2017-08-23 (main key ID AA79CCAE)

    [master (root-commit) 2814856] Works...?
     1 file changed, 0 insertions(+), 0 deletions(-)
     create mode 100644 file.txt

    Note: One can also use the the -S option as alternative to using the commit.gpgsign true config, but as a forgetful person, I’d advice against that… Either set the config globally, or for the specific repo you need it for.

  2. Verify commit was signed:
    🔷 $ git log --show-signature
    commit 2814856365a07b3deb374f1337258102c06b77ef
    gpg: Signature made 08/23/17 06:18:50 W. Europe Daylight Time^M
    gpg:                using RSA key 6ADB9D4262275E24^M
    gpg: Good signature from "Alice Person (alice) <alice.person@example.com>" [ultimate]^M
    gpg:                 aka "Alice Person (alice) <alice@example.org>" [ultimate]^M
    Author: Alice Person <alice.person@example.com>
    Date:   Wed Aug 23 06:18:48 2017 +0200

        Signed commit
  3. Add a signed tag, using -s:
    🔶 $ git tag -s v1 -m "Signed tag"

    You need a passphrase to unlock the secret key for
    user: "Alice Person (alice) <alice.person@example.com>"
    4096-bit RSA key, ID 62275E24, created 2017-08-23 (main key ID AA79CCAE)

    Note: Unfortunately, unlike for commits, there is no tag.gpgsign true config as of writing, so to sign tags the -s option has to be remembered.

  4. Verify tag was signed:
    🔷 $ git tag -v v1
    gpg: Signature made 08/23/17 06:34:18 W. Europe Daylight Time
    gpg:                using RSA key 6ADB9D4262275E24
    gpg: Good signature from "Alice Person (alice) <alice.person@example.com>" [ultimate]
    gpg:                 aka "Alice Person (alice) <alice@example.org>" [ultimate]
    object 53e7f2e637eaf3c47b5dcad30b57be7b6829be02
    type commit
    tag v1
    tagger Alice Person <alice.person@example.com> 1503462856 +0200

    Signed tag

Add GPG key to GitHub

  1. Export the public key:
    🔶 $ gpg -a --export alice > public.txt
  2. Copy it.
  3. Go to GPG keys on GitHub.
  4. New GPG Key.
  5. Paste it.
  6. Add GPG Key.
  7. Pushed commits and tags should now look verified, as in this post: GPG signature verification

Sources: help.github.com, StackOverflow, git-scm.com

PHP: Unset all defined variables

foreach(get_defined_vars() as $k => $v)
    unset($$k);
unset($k, $v);

For example handy in this setting:

foreach($iterable as $item)
{
    extract($item);
    unset($item);

    // Define another variable, for only some of the items
    if($foo == 'bar')
        $x = 2;

    // Yield all defined vars
    yield get_defined_vars();

    // Cleanup, to prevent $x and other variables from
    // sticking around to the next iteration
    foreach(get_defined_vars() as $k => $v)
        unset($$k);
    unset($k, $v);
}