Blogs

Why decoupling Drupal

Amongst other things, I hear this quite a lot on my conversations around the subject, why decoupling Drupal, is not like you are giving away what Drupal is and overkilling with something you could do with other tools? What's the point?

Well, in this keynote talk on Design4Drupal Dries mentions something interesting. Everyone things on Mongodb or any other cool technology in order to build your api... but what about the backend, the administration of that api? Who is going to input and maintain the content there? Will you have to build something from scratch?

Well, this is where Drupal decoupled comes into action. Why not having something that is API first ready and designed specifically to manage content?

Links:

categorias: 

Executing memcached in Travis

So, I heard you need Drupal and memcached running in Travis, right? But you have this "little" issue that Travis/Drupal cannot connect to memcached, something like:

WD memcache: You must enable the PHP memcache (recommended) or [error] memcached extension to use memcache.inc. 
WD memcache: Failed to connect to memcache server: 127.0.0.1:11211 [error]

Before you jump into docs and tutorials on how to install memcached in Travis, probably it's already there, you just have to enable.

Simply add a new php.ini file somewhere in your source, for example in travis_scripts/php.ini:

extension = "memcached.so"

and point that from your Travis, for example from your before_install section:

phpenv config-add travis_scripts/php.ini

Or even better, from your setup_environment.sh or equivalent

Your error should have gone now.

RuntimeException: Could not delete docroot/core/.git/ ...

First sign of something going wrong, you do a composer update and get this in the middle:
 
  [RuntimeException]

  Could not delete docroot/core/.git/hooks/applypatch-msg.sample:
You can get different messages, core path, whatever. Important to notice is that the process (composer) has been suddenly interrupted. Worst thing is that, after this, you just get:
  [RuntimeException]

  Source directory docroot/core has unpushed changes on the current branch:

  Branch master could not be found on the origin remote and appears to be unpushed
after you try any composer update or install, so you are blocked.
[email protected]:/var/www/vecfullmig$ rm -rf docroot/core/.git/

rm: cannot remove /docroot/core/.git/info/exclude Permission denied

...

Solution is simple, just check what you have in that folder (docroot/core). Its just generated code via composer, so you are good to remove it:
[email protected]:/var/www/vecfullmig$ exit

logout

Connection to 127.0.0.1 closed.

[email protected]:~/projects/personal/vec/vecd8-fullmigration/vecfullmig$ rm -rf docroot/core/

[email protected]:~/projects/personal/vec/vecd8-fullmigration/vecfullmig$ composer update

    1/2:    http://packagist.org/p/provider-latest$d62e317bf7d5968846ee2c0b922c14df60b0c1ca3ae7f714b5e2cb0a1afd1ace.json

    2/2:    http://packagist.org/p/provider-2018-04$f7d80ec02ae656c3d18ff3dedb552ff63a2f728f4ec718d15443f45741f8ab23.json

    Finished: success: 2, skipped: 0, failure: 0, total: 2

Gathering patches for root package.

Removing package drupal/entity_browser so that it can be re-installed and re-patched.

  - Removing drupal/entity_browser (2.0.0-alpha2)

Deleting docroot/modules/contrib/entity_browser - deleted

Removing package drupal/entity_embed so that it can be re-installed and re-patched.

  - Removing drupal/entity_embed (1.0.0-beta2)

Deleting docroot/modules/contrib/entity_embed - deleted

Removing package drupal/media_entity_instagram so that it can be re-installed and re-patched.

But it's still resisting itself. Leave the vm, remove it from the host and all good to continue:

[email protected]:/var/www/vecfullmig$ exit

logout

Connection to 127.0.0.1 closed.

[email protected]:~/projects/personal/vec/vecd8-fullmigration/vecfullmig$ rm -rf docroot/core/

[email protected]:~/projects/personal/vec/vecd8-fullmigration/vecfullmig$ composer update

    1/2:    http://packagist.org/p/provider-latest$d62e317bf7d5968846ee2c0b922c14df60b0c1ca3ae7f714b5e2cb0a1afd1ace.json

    2/2:    http://packagist.org/p/provider-2018-04$f7d80ec02ae656c3d18ff3dedb552ff63a2f728f4ec718d15443f45741f8ab23.json

    Finished: success: 2, skipped: 0, failure: 0, total: 2

Gathering patches for root package.

Removing package drupal/entity_browser so that it can be re-installed and re-patched.

  - Removing drupal/entity_browser (2.0.0-alpha2)

Deleting docroot/modules/contrib/entity_browser - deleted

Removing package drupal/entity_embed so that it can be re-installed and re-patched.

  - Removing drupal/entity_embed (1.0.0-beta2)

Deleting docroot/modules/contrib/entity_embed - deleted

Removing package drupal/media_entity_instagram so that it can be re-installed and re-patched.

Happy days :-)

categorias: 

Parse error: syntax error, unexpected ':', expecting ';' or '{' in vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php on line 50

Easy error to fix, once you know what's going on (is not always the case?).

Just upgrade your system from php 5 to php7. Drupal8 requirement.

In BLT, just edit your box/config.yml and change this line

php_version: "5.6"

to this:

php_version: "7.2"

Good old vagrant provision should do the rest of the trick. You are welcome :-)

categorias: 

HEAD detached from origin/master

Everything starts with a problem trying to checkout your repository master branch:

git checkout master
error: pathspec 'master' did not match any file(s) known to git.

Trying to checkout origin does not improve things, but at least is a step forward:

git checkout origin/master
Note: checking out 'origin/master'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at d1389fef9... Merge pull request #4

Now, problem, your master branch is detached in your local.

Solution, create a new branch from that state:

git checkout -b temp

And point master to that new branch

git branch -f master temp

Now you can push to your origin branch to update also in github or your remote repository.

categorias: 

Acquia BLT short Drupal8 howto

Working with vm’s makes everything simpler and easier. Easy to reproduce bugs, easy to reproduce features between environments and, most importantly, between developers.

In the past I’ve been working with different solutions, custom mainly, based on puppet, ansible…. Until I arrived to Acquia. Local environments as it happens is a recurrent topic on every team, a clear pattern… and when there is a pattern, you can write something to save some time to those lazy developers ;-). Enter BLT (Pronounced BOLT).
 
BLT is basically an environment that has everything ready for fast developer on-boarding, easy deployment on different environments (dev, staging, prod, … and of course, local), but also for quick automation of repetitive tasks, like rebuilding your sites, pulling databases...
 
Configuring BLT is very straightforward, but it will take some reading from you. Keep reading for a TL;DR version:
 
PRE-REQUIREMENTS
 
First, install the requirements: https://github.com/acquia/blt/blob/8.x/INSTALL.md
 
In Mac it is very easy to do it simply following the brew requirements.
 
 
Basically:
 
brew tap caskroom/cask

brew install php56 git composer ansible drush

brew cask install virtualbox vagrant
 
Once this is installed you have blt in your command line:
 
  blt --version
 
That’s it, you are ready.
Note: for other operating systems please visit: https://github.com/acquia/blt/blob/8.x/readme/local-development.md
 
INSTALLING YOUR NEW SITE(s)
 
Once we have all the tools installed in our computer we can start building apps. It couldn’t be simpler:
 
    composer create-project --no-interaction acquia/blt-project MY_PROJECT
 
That will create a base directory from which you can start building your Drupal app. First thing I’d do is moving this to your git repo, i.e. GitHub:
 
  $ git add .

  $ git commit -m "BLT-00 first commit."

  $ git remote add origin https://github.com/alex-moreno/blt_test.git

  $ git push -u origin master
 
Now, let’s move inside the repo and start doing the magic. Let’s initialise the vm (I am assuming here that we’ll be working on a virtual machine):
 
  blt vm
 
It will ask if you want to install Drupalvm, to which we’ll say yes, and afterwards if we want to boot it. Yes again.
 
At the end of the process you should see a green message like this one:
 
"Drupal VM booted successfully. Please use vagrant commands to interact with your VM from now on.”
 
Your vm is ready. Last stop, install a site:
 
 
  # Since blt 9.x, you have to do this from inside the vm, so:
  vagrant ssh 
  blt setup
 
This will install a default Drupal 8 site in docroot. You could put your custom site here, or for example install lighting (https://docs.acquia.com/lightning) instead of the default one. The best practice for that road would be using composer, although I’ll leave this for a different post.
 
CONNECTING EVERYTHING TO ACQUIA CLOUD
 
Now, next step you need is to actually connect your new vm to your Acquia Cloud (AC) environments. You have to do this drush level and BLT level, drush to be able to execute drush against the environments, BLT to be able to sync the databases, build artifacts, etc…
 
First bit, BLT settings. Edit:
 
blt/project.yml
 
And add in remotes the url to AC. You’ll find this url in AC. Go to https://cloud.acquia.com, select your application and, in the list of environments, you’ll see on top right an icon called “Application Information”. Click and the first url is what you need. IE: [email protected]:YOUR-APP.git
 
Your yml file will look like this:
 
git:

  default_branch: master

  remotes:

   - '[email protected]:lightningalex.git'
 
Lastly, your drush settings. Go to your AC profile page: https://accounts.acquia.com/account
 
Select Credentials and, after confirming your password, you should see 'Drush integration’ in the new page. Download and place the hidden files in your $HOME.
 
DEPLOYING
 
Time to deploy your stuff to Acquia Cloud (or theoretically any other host provider). First thing, you’ll need to add your ssh keys to Acquia Cloud, just:
 
 
If you don't have any ssh keys yet there are some good short tutorials out there, it shouldn't take you more than 10 minutes to generate a new ones.
 
Ready to go, do:
 
blt deploy -Ddeploy.commitMsg='BLT-000: Deployment test' -Ddeploy.branch='master-build'
 
Answer ‘y’ to create a tag, return for the default commit message, and write your tag (i.e.: 1.0.3-build)
 
If your keys are good to go you should see some magic happening, and your artefact being deployed to the Acquia Cloud remote server. Now simply go to Acquia Cloud, select the tag that you have just created and deploy it in your environment. 
 
All done… although now I am thinking on changing the title of the article… not that short after all :-)
 
 
Bonus: Some commands
 
- Rebuild your local with the remote db:
 
blt sync
 
Equivalent to: drush sql-sync @remote @local
 

Ansistrano, deploying Drupal with Ansible

Last months have been pretty busy here at BBC Worldwide with some of the projects we've been involved in.

In my case, one of the main areas I’ve been trying to improve (apart of the daily busy routine) is our devops / CI approach. The previous approach was using Chef, but it was not really adopted by the developers (which meant that after some months, the system was broken) and we were lacking some fundamental things (like integration with the production system, a real CI flow, etc…).

On the other hand, my previous experience with puppet was that the system grew too much to be easily maintained, specially if you don’t have a big dedicated devops team. To sum up, during last months research I was pretty amazed with Ansible, it's amazingly simple, very flexible and a truly joy to maintain. So, to me, the way forward was Ansible.

So, we started rewriting some of the old broken features in Chef and, sooner than later, we found ourselves reinventing the wheel. Some features were custom things, like triggering "drush cc all”, executing grunt, phpcs, etc... but obviously lots others were not… well, we are not the first team in needing an apache and mysql database, are we?

And deployment is one of these things that I was not too keen to reinvent. It would be pretty simple with Ansible, to be honest, but why not use something that is already tested, works well and at the same time give some love back to the community? Enter Ansistrano.

Ansistrano is a deployment tool based in Ansible. The relation with Capistrano ends just here, with the name similarity (no code base was harmed during the process). For more information about Ansistrano please visit the official repository: https://github.com/ansistrano/deploy

- Step 0. Install ansistrano (deploy and you’ll probably be interested in the rollback too):

ansible-galaxy install carlosbuenosvinos.ansistrano-deploy carlosbuenosvinos.ansistrano-rollback

- Step 0. Clone the deploy repo in the folder you’ll be using the app. Let’s say we’ll be working in ~/my-app-build :

git clone https://github.com/ansistrano/deploy.git ansistrano-deploy

Notice that we are cloning the deploy repository.

We’ll be using the latest stable release, list tags:

[email protected]:~/my-app-build$ git tag
1.0.0
1.1.0
1.2.0
1.3.0
1.4.0
1.4.1

at the moment, the latest stable release is 1.4.1, so:

git checkout 1.4.1

Step 1. Now, the ‘tricky part’. We are going to write a file where we’ll execute all the magic. Let’s call it build-my-app.yml:

---
- name: Deploy example app to local.myapp.com
  hosts: all
  vars:
    ansistrano_deploy_to: "/var/www/myapp.local"
    ansistrano_keep_releases: 3
    ansistrano_deploy_via: "git"
    ## GIT pull strategy
    ansistrano_git_repo: [email protected]:myapp-in-git.git
    ansistrano_git_branch: develop
    ansistrano_git_identity_key_path: ""

  roles:
    - { role: ansistrano-deploy }

Notice that the role we have at the end is just the deploy repository cloned from Ansistrano (https://github.com/ansistrano/deploy). You can change the name, as I've done in this example (ansistrano-deploy) but you'll have to upgrade the roles variable in your yml (again, as shown in this example).  

Step 2. Run deploy:

ansible-playbook -i "localhost," -c local build-my-app.yml -vvv

Instead of specifying localhost you could also use a hosts file, as recommended in the official documentation. This is also going to give you the freedom of deploying your app not just in your local environment, but potentially in any remote server, i.e. aws, digital ocean, etc...

Step 3 (optional). From here, the limit is the sky. In our case, we have some complex deployments running grunt, drush, clearing cache… The advantage here is that ansible is pretty flexible, so you could for example add your own tasks in your deploy file (build-my-app.yml), i.e.:

tasks:
  - include: goodfood/tasks/apt.yml

The right, official way of doing this is using the hooks that ansistrano itself offers you:

  # Hooks: custom tasks if you need them
  ansistrano_before_setup_tasks_file: "{{ playbook_dir }}/<your-deployment-config>/my-before-setup-tasks.yml"
  ansistrano_after_setup_tasks_file: "{{ playbook_dir }}/<your-deployment-config>/my-after-setup-tasks.yml"
  ansistrano_before_update_code_tasks_file: "{{ playbook_dir }}/<your-deployment-config>/my-before-update-code-tasks.yml"
  ansistrano_after_update_code_tasks_file: "{{ playbook_dir }}/<your-deployment-config>/my-after-update-code-tasks.yml"
  ansistrano_before_symlink_shared_tasks_file: "{{ playbook_dir }}/<your-deployment-config>/my-before-symlink-shared-tasks.yml"
  ansistrano_after_symlink_shared_tasks_file: "{{ playbook_dir }}/<your-deployment-config>/my-after-symlink-shared-tasks.yml"
  ansistrano_before_symlink_tasks_file: "{{ playbook_dir }}/<your-deployment-config>/my-before-symlink-tasks.yml"
  ansistrano_after_symlink_tasks_file: "{{ playbook_dir }}/<your-deployment-config>/my-after-symlink-tasks.yml"
  ansistrano_before_cleanup_tasks_file: "{{ playbook_dir }}/<your-deployment-config>/my-before-cleanup-tasks.yml"
  ansistrano_after_cleanup_tasks_file: "{{ playbook_dir }}/<your-deployment-config>/my-after-cleanup-tasks.yml"

where playbook_dir is the folder where your yml file lives.

That's it. Simple, elegant, and really powerful, I love it :-). Next episode, we'll talk about the rollback artifact.

Notes: Amended Step 0, as you don't need to install the playbook through the ansible galaxy, just cloning would do. Thank you Carlos Buenosvinos.

Software Craftsmanship definition

Software Craftsmanship is a mindset— a lifestyle that many professional developers adopt. Software craftsmen live and breathe software. They see software as a craft and are committed to do whatever they can to master their craft

Ingeniería y cafe

"Un ingeniero es una máquina que convierte café en diseños, construcciones y líneas de código." Parafraseando a Alfréd Rényi

categorias: 

Bad code

Don’t comment bad code— rewrite it.

Brian W. Kernighan and P. J. Plaugher1