Push to deploy Vue app

With this workflow, my web space contains a git remote which, whenever pushed to, builds the Vue project and puts it on a public path.

A few years ago I, working with Drupal 8, I was using Pantheon and I really enjoyed the workflow, where deploying comprised of simply git push‘ing to a certain remote. (I think maybe this model was made popular by Heroku?)

Nowadays I’m getting into JS development. A framework that I have been using recently is Vue. One of my current project ideas is using Vue to develop a small web app for crawling some websites and grabbing data on arbitrary movies. I want to do the development in short iterations, and I want it to be easy to publish each step of progress.

So today I set up a push-to-deploy workflow for my Vue app. I don’t want to give the prototype its own domain name, so I’m publishing it in a subdirectory: klavaro.se/filminfo

Workflow

With this workflow, my web space contains a git remote which, whenever pushed to, builds the Vue project and puts it on a public path.

The deploy procedure is reduced to a single command: git push deploy

Git setup on server

The web host I am using is NearlyFreeSpeech.net, which provides SSH access and git.

SSH into the server and create the remote repository:

cd /home/private
git init --bare /home/private/myproject.deploy

Clone it to get the local git repository:

git clone myproject.deploy myproject.checkout

Then add a post-receive hook script in the remote repository:

touch myproject.deploy/hooks/post-receive
chmod +x $_
# Bonus trick: That $_ expands to the last argument in the previous command, in this case the path of the new file.

Edit the script as follows (making changes where appropriate, depending on your Vue setup):

!/bin/bash
# -e exits as soon as any command fails
# -x prints each command being executed
set -ex
CHECKOUT=/home/private/myproject.checkout
SITE=/home/public/myproject
cd $CHECKOUT
git --git-dir .git fetch
git --git-dir .git reset --hard origin/master
yarn install --production
yarn build --dest $SITE

Local git configuration

Back on your local machine, all you have to do is add the new remote:

git remote add deploy user@example.com:/home/private/myproject.deploy

Give it a spin:

echo Hello World! > hello.txt
git add hello.txt
git commit -m 'Deploy test'
git push deploy
# Verify that the post-receive script output is showing.
# Clean up after yourself:
git reset --hard HEAD^
git push -f deploy

Configure Vue for a subdirectory

Vue is normally configured to serve the app at the root level of the host. I want to serve it at the root level locally, but in a subdirectory on the web server. I accomplished this using environment variables.

Locally, create .env containing:

PUBLIC_PATH=/

Edit vue.config.js like this:

module.exports = {
  publicPath: process.env.PUBLIC_PATH,
} 

If you use vue-router, configure it (in main.ts):

const router = new VueRouter({
  base: process.env.PUBLIC_PATH,
  // ...
})

Finally, in the local repository on the server (that’s an oxymoron, but you know what I mean), create .env.local, containing:

PUBLIC_PATH=/myproject

After that, commit and push the changes you made on your local machine.

Customer-specified price in Drupal 7 Commerce

Today, I spent several hours messing about with the Rules UI and googling Commerce docs and forums, trying to figure out how to provide a field where the customer can freely choose the price of a donation-style product. In the end, I found pointers to a method which turns out to work pretty well.

My use case

Donation as a Drupal 7 Commerce product. Donation amount can be chosen freely, above a fixed minimum. The customer/donor receives a reward (but that is not actually relevant here).

Howto

This is how I did it:

  1. Install Commerce Customizable Products
  2. Add price field
    1. Add a line item type at admin/commerce/config/line-items. It is created with a bunch of default fields, which you cannot change.
    2. Add a field of the Price type (TODO: Figure out how to set a minimum)
  3. Make it visible
    1. At the field display settings of your product display content type (something like admin/structure/types/manage/product-display/display), edit the settings for the product reference field. Change Add to Cart line item type to your new line item type. Click Update and Save.
  4. Make it count
    1. Add a new rule at admin/config/workflow/rules. Choose the event Calculating the sell price of a product.
    2. Add an Entity has field condition with commerce-line-item for Entity and your price field for Field.
    3. Add a Set the unit price to a specific amount action with commerce-line-item for Line item and something like commerce-line-item:field-donation-price:amount for Amount.

Single-machine dev mail setup

I sometimes work on websites where sending email is a central task. To be able to efficiently test my code on my Ubuntu development machine, I have created a simple setup from the following requirements:

  1. No mail should reach the internet
  2. I should be able to quickly read every message that is “sent” from PHP

The strategy is to use Postfix to catch and save messages (and enable mail() at all), and Mutt to read them without any fluff. Continue reading “Single-machine dev mail setup”