d
WE ARE EXPERTS IN TECHNOLOGY

Let’s Work Together

n

StatusNeo

Breaking The GitHubbing Myth: Extended SCM using GitHub Actions and GitHub Packages

GitHub is the most popular Source Code Management tool! Is it now? Let’s see a meme xD!

GitHub is indeed the most popular source code management tool but Microsoft were shocked to see that the platform lost a huge amount of its users within one year of its acquisition of GitHub.

The main issue can be related to Darwin’s theory of the survival of the fittest. Software industry changes at a pretty incredible pace and even the most popular of tools must keep upgrading themselves to stay relevant. GitHub lost its users because it had not evolved from source code management tool to something new, unlike its alternatives like GitLab that had advanced Continuous Integration, Container Management System and Artifactory Management.

That all changed by the end of 2019. GitHub launched new features GitHub Actions for continuous integration and GitHub Packages for package management/artifactory.

Let’s see a sample use case for the integration of GitHub with GitHub Actions and GitHub packages.

Technology Stack

Java: Programming Language

GitHub: Source Code Management

GitHub Actions: Continuous Integration

GitHub Packages: Artifactory Management

Apache Maven: Build Automation

Docker: Container Management and remote servers

The workflow in action

The aim is to push Java source files to GitHub and the push action triggers continuous integration using GitHub Actions. The java source files are copied to remote docker container, built using Apache Maven and tested. The docker container is then transformed into a docker image and pushed to GitHub Package’s Docker Registry.

Create a Dockerfile in the root of the GitHub repository.

# Base Image - ubuntu latest
FROM ubuntu

# Upgrade and Update the Linux Packages
RUN apt-get -y upgrade && apt-get -y update

# Setup Development Environment

## Install Java
RUN apt install -y openjdk-11-jre-headless
RUN java --version

## Install Apache Maven
RUN apt install -y maven
RUN mvn --version

# Install Tree to see the maven directory structure
RUN apt install -y tree

# Create a Maven Skeleton Project using the Command line
RUN mvn archetype:generate -DgroupId=nish -DartifactId=nish -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false

# Change Working Directory to the [Artifact_Id/]
WORKDIR /nish/

# Add all java source files from GitHub repository to current working directory in /[artifact_id]/src/main/java/[group_id]/
ADD java/*.java /nish/src/main/java/nish/
RUN tree

# RUN Maven Goals
RUN mvn clean
RUN mvn compile
RUN mvn test
RUN mvn install
RUN mvn site

Important points about the Dockerfile:

  • Docker Image uses Ubuntu Linux as base image
  • The ubuntu image is updated to its latest packages
  • Java and Apache Maven are installed on the docker image
  • A generic Maven project and its configuration file pom.xml is created via the commandline.
  • A sync folder is created to synchronize the java source files in GitHub repository and the directory on the Docker Image.
  • Maven goals are executed sequentially on the java source files.

To setup continuous integration using GitHub Actions, create its declarative script file main.yml in .github/workflows directory on GitHub repository,

name: Java Accelerator
on:
  push
env:
  IMAGE_NAME: [Docker Image name]

jobs:
  push:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - name: Create Docker Image for Development Environment
        run: docker build . --file Dockerfile --tag $IMAGE_NAME

      - name: Log into GitHub Package's Docker Registry
        run: echo "${{ secrets.GH_TOKEN }}" | docker login docker.pkg.github.com -u ${{ github.actor }} --password-stdin

      - name: Push Docker Image to GitHub Packages
        run: |
          IMAGE_ID=docker.pkg.github.com/${{ github.repository }}/$IMAGE_NAME
          
          # Change all uppercase to lowercase
          IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')

          # Strip git ref prefix from version
          VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')

          # Strip "v" prefix from tag name
          [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')

          # Use Docker `latest` tag convention
          [ "$VERSION" == "master" ] && VERSION=latest

          echo IMAGE_ID=$IMAGE_ID
          echo VERSION=$VERSION
          
          docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
          docker push $IMAGE_ID:$VERSION

Important points about the automation script:

  • Creates the development environment in Docker container using the specified Dockerfile
  • The docker container is transformed into a template docker image
  • The command line is used to automatically login into our GitHub Package registry using GitHub secrets.
  • The docker image is pushed to GitHub packages and hosted publically.
  • This automation script is triggered after every push/commit on the GitHub repository.

Visit GitHub Repository for all the files required to setup this workflow.

Spinning up the Docker Container using the Docker Image hosted on GitHub Packages

GitHub Packages maintained by the connected repositories can be visited by the clicking on the Package tab in the homepage of the repository.

Visit GitHub Packages to use the Docker Image generated by this workflow.

  • Pull the Docker Image on the local workstation’
  • Inspect the Docker Image ID
  • Spin up a Docker container using the image ID of the pulled image and verify that Java and Maven are installed on it.
  • Run the tree command to see the directory structure and dependency map Maven has automatically created for us.
  • Run Apache Maven goals.

I hope this blog might break some of the myths related with GitHub platform and help kick start your journey beyond source code management and into automation and package management

Principal DevOps Evangelist and Consultant at StatusNeo

Comments

  • Rishabh Negi

    June 21, 2020

    Sir, I was struggling to automate the Java workflow but now its working! Kudos đŸ™‚

Add Comment