Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a Hello World action #4

Merged
merged 6 commits into from
Nov 26, 2021
Merged

Add a Hello World action #4

merged 6 commits into from
Nov 26, 2021

Conversation

Cemberk
Copy link
Owner

@Cemberk Cemberk commented Nov 26, 2021

No description provided.

@github-learning-lab
Copy link
Contributor

Write the Hello World source code

Great job @Cemberk, you now have action metadata for your first action. The next piece we will add will be the logic of our action. In this case, our logic will be written in Go.

If you are not familiar with Go programming that's perfectly okay, you are here to learn about writing actions! All the necessary code for each language will be provided for you!

The first iteration of our action will follow the traditional path of logging "Hello World" 👋to the console. We will expand on this as we move forward, for now it's a good test to make sure all of our files are set up correctly 😄

⌨️ Activity: Create main.go containing the Hello World source code

  1. Create and add the following contents to the .github/actions/hello-world/main.go file:
    You can use this link to easily create this file in the proper location.

    package main
    
    import "fmt"
    
    func main() {
        fmt.Println("Hello Docker Actions")
    }
  2. Commit the changes to this branch

  3. Click the green Commit new file button

📖 Learn Go programming


I'll respond when you push changes to this pull request.

@github-learning-lab
Copy link
Contributor

Awesome 🎉

This action now has two of the three key files it needs to run:

  • Source code
  • Metadata

Create the action's Dockerfile

Lastly we will create the Dockerfile. Like with Go programming, it is perfectly okay if you are not a Docker guru, we will provide the needed code snippets for your Dockerfile.

⌨️ Activity: Create a Dockerfile containing the Docker instructions

  1. Create and add the following contents to the .github/actions/hello-world/Dockerfile file:
    You can use this link to easily create this file in the proper location.

    FROM golang:1.15
    WORKDIR /go/src/hello
    COPY . .
    RUN go get -d -v ./...
    RUN go install -v ./...
    CMD ["hello"]
  2. Commit the changes to this branch

  3. Click the green Commit new file button

📖 Become a Dockerfile guru


I'll respond when you push changes to this pull request.

@github-learning-lab
Copy link
Contributor

Congratulations 🎉

Your very first Docker action has been written and executed within a workflow! You may be wondering how I know that and the truth is that GitHub Actions provide real-time logging of the events happening within the runner! Since our action prints to the console we can just expand that step in our workflow and look at the standard output that is on our screen.

You can do this in your own Actions tab or you can settle for examining the screenshot below to see our Hello World statement in place of where our previous errors existed.

hello world success


Whoa, that's a lot of output for a simple hello world! Don't let this alarm you, the output you see is from the Docker build operation that packages up your files into a Docker image.

📖 Learn about Docker build

@github-learning-lab
Copy link
Contributor

Using input parameters

A "Hello World" message is great, but let's personalize it a little bit. We will do this by adding an input parameter to the action.yml, workflow.yml and main.go files.

Although this example may seem a little lightweight input parameters have a very flexible use case. Consider a scenario where you need to access secret API key with your action, or when you need to specify the path to a given file. Inputs allows for these problems to be easily solved.

A quick example

To add inputs we need to add the inputs: parameter to the action.yml file. The inputs: parameter has a few parameters of its own.

Parameter Description Required
description: String describing the purpose of the input True
required: Boolean value indicating if the input parameter is required or not. (Default value is True) False
default: String representing a default value for the input parameter False

Let's take a look at how this fits into an action.yml file.

action.yml

name: "my hello action"

description: "say hello with actions"

inputs:
  firstGreeting:
    description: "who would you like to greet in the console"
    required: true
    default: "Hubot"

  secondGreeting:
    description: "another person to greet"
    required: true
    default: "Mona the Octocat"

  thirdGreeting:
    description: "a third greeting"
    required: false

The placement of your inputs: is not strictly enforced, however it has become commonplace to ensure the runs: statement is defined after your inputs: and outputs: in your action.yml file.


So what is actually happening here?

Well, in the my-workflow.yml file we could specify values for inputs we just created:

  • first-greeting
  • second-greeting
  • third-greeting

Or we could leave them out and rely on their default values.

The example below demonstrates a mix of both:

my-workflow.yml

name: "Docker Actions"

on: [push]

jobs:
  action:
    runs-on: "ubuntu-latest"
    steps:
      - uses: actions/checkout@v1

      - name: "hello-action"
        uses: ./.github/actions/hello-world
        with:
          firstGreeting: "Learning Lab User"

Now that there are inputs in the action's metadata the user can interface with them by supplying values. In this case Learning Lab User was passed as the value for the firstGreeting input which overrides the default value, specified in the action.yml, of Hubot


main.go

package main

import (
	"fmt"
	"os"
)

func main() {

  // Access Inputs as environment vars
  firstGreeting := os.Getenv("INPUT_FIRSTGREETING")
  secondGreeting := os.Getenv("INPUT_SECONDGREETING")
  thirdGreeting := os.Getenv("INPUT_THIRDGREETING")

  // Use those inputs in the actions logic
  fmt.Println("Hello " + firstGreeting)
  fmt.Println("Hello " + secondGreeting)

  // Someimes inputs are not "required" and we can build around that
  if thirdGreeting != "" {
    fmt.Println("Hello " + thirdGreeting)
    }

}

In our actions source code we can access the inputs as if they are environment variables. GitHub Actions takes every inputs: value and converts it by adding INPUT_ and making the value uppercase.

For example:

  • firstGreeting = INPUT_FIRSTGREETING
  • secondGreeting = INPUT_SECONDGREETING
  • someInput = INPUT_SOMEINPUT

How you access environment variables will vary by language


📖Read more about the input parameter

@github-learning-lab
Copy link
Contributor

Add input parameters to Hello World's metadata

Now that we know what input parameters are, let's edit the metadata for our hello-world action.

⌨️ Activity: Update action.yml to accept input parameters for Hello World

💡All of the following steps take place inside of the .github/actions/hello-world directory.

  1. Add the following contents to the .github/actions/hello-world/action.yml file:
    You can use this link to easily edit this file.

    name: "my hello action"
    
    description: "say hello with GitHub Actions"
    
    inputs:
      firstGreeting:
        description: "who would you like to greet in the console"
        required: true
        default: "Hubot"
    
      secondGreeting:
        description: "another person to greet"
        required: true
        default: "Mona the Octocat"
    
      thirdGreeting:
        description: "a third greeting"
        required: false
    
    runs:
      using: "docker"
      image: "Dockerfile"
  2. Commit the changes to this branch


I'll respond when you push changes to this pull request.

@github-learning-lab
Copy link
Contributor

Use input parameters in the source code

Great job 👍 next let's update our source code to consume the inputs that are now defined.

⌨️ Activity: Extend Hello World's source code to accept the input parameters

💡All of the following steps take place inside of the .github/actions/hello-world directory.

  1. Add the following contents to the .github/actions/hello-world/main.go file:
    You can use this link to easily edit this file.

    package main
    
    import (
        "fmt"
        "os"
    )
    
    func main() {
    
    // Access Inputs as environment vars
    firstGreeting := os.Getenv("INPUT_FIRSTGREETING")
    secondGreeting := os.Getenv("INPUT_SECONDGREETING")
    thirdGreeting := os.Getenv("INPUT_THIRDGREETING")
    
    // Use those inputs in the actions logic
    fmt.Println("Hello " + firstGreeting)
    fmt.Println("Hello " + secondGreeting)
    
    // Someimes inputs are not "required" and we can build around that
    if thirdGreeting != "" {
        fmt.Println("Hello " + thirdGreeting)
        }
    
    }
  2. Commit the changes to this branch


I'll respond when you push changes to this pull request.

@github-learning-lab
Copy link
Contributor

Use input parameters in the workflow

The last piece to this actions puzzle is to edit the workflow file so that we can set custom values for these inputs.

⌨️ Activity: Assign values to the newly created input parameters in my-workflow.yml

💡All of the following steps take place inside of the .github/workflows directory.

  1. Add the following contents to the .github/workflows/my-workflow.yml file:
    You can use this link to easily edit this file.

    name: "Docker Actions"
    
    on: [push]
    
    jobs:
      action:
        runs-on: "ubuntu-latest"
        steps:
          - uses: actions/checkout@v1
    
          - name: "hello-action"
            uses: ./.github/actions/hello-world
            with:
              firstGreeting: "Learning Lab User"
  2. Commit the changes to this branch


I'll respond when you push changes to this pull request.

@github-learning-lab
Copy link
Contributor

Take a 👀 at what you made!

Great Job 👍 making those changes @Cemberk. I will take just a moment to walk you through what happened.

If you look at the screenshot below you will see a very similar output to what your results should show. If you'd like you can open your own Actions tab to follow along.

results from using input

Your action now says hello to Learning Lab User which was the specified value for the firstGreeting input parameter which was added to the my-workflow.yml file.

What's interesting though, is that we also see Mona the Octocat and if you recall that is the value of the secondGreeting parameter in the action.yml file.

Why do we see the value of the secondGreeting 🤔

If you remember, we made the secondGreeting input parameter required. This means that even if it is not specified in my-workflow.yml it will be executed by the main.js code using whatever value was set as default. It cannot be ignored like our thirdGreeting was.

Circling back to the fistGreeting you may have noticed that you were able to overwrite the default value of Hubot by being explicit in the my-workflow.yml file.

Had you been explicit with thirdGreeting in the my-workflow.yml file then the if statement in the main.go file would have executed and you would have three inputs.

@github-learning-lab
Copy link
Contributor

Explore your input parameters

Take a few minutes to play with the current code you have. I don't suggest editing the main.go, Dockerfile, or action.yml files, rather I think there is a lot to gain by changing the my-workflow.yml file to include or exclude certain input parameters.

⌨️ Activity: View the results of changing input parameters

  1. Remove all the input parameters from the my-workflow.yml file. What happens when your action executes?
  2. Add all three input parameter and be explicit with their values in the my-workflow.yml file. What happens when your action executes?
  3. Specify only the third-greeting input parameter in the my-workflow.yml file. what happens when your action executes?

When you are finished experimenting and examining the results merge this pull request into the main branch.

Our next lesson will show you how to add external libraries to an action as well as interact with external APIs.


When I notice that you have merged this branch I will open a new issue in your repository to continue guiding you.

@Cemberk Cemberk merged commit fdc765c into main Nov 26, 2021
@github-learning-lab
Copy link
Contributor

Congrats on your first Action 🎉

Congratulations Cemberk you have officially written your first GitHub Docker action!!!

That's super exciting news, but this lesson has just started, so let's head over to the new issue I've opened to continue writing GitHub Actions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant