March 30, 2023

New Fermyon Cloud Features: GitHub Actions and App Metrics

MacKenzie Olson MacKenzie Olson

cloud spin wasm

New Fermyon Cloud Features: GitHub Actions and App Metrics

Well hello there! I’m a new face here on the Fermyon Blog so allow me to introduce myself. My name’s MacKenzie Olson and I’m a product manager here at Fermyon. As a fan of all things serverless, I’m looking forward to sharing a few of the new features we’ve been working on for Fermyon Cloud; our serverless platform for WebAssembly (Wasm) functions and microservices.

When considering a recipe for a delightful developer experience on a serverless platform, observability and integration with familiar developer tools are two critical ingredients. With that in mind, we’ve been cooking up a few new features to bring that experience to life on Fermyon Cloud. Let’s use a specific workload to guide our experience, as we take a peak into what we’ve been adding to Fermyon Cloud.

Don’t Underestimate The Humble Webhook: A Workload Example

A frequent inquiry we get from new Fermyon Cloud users is “what sort of workloads are best suited for the platform?”. Given the blazing-fast cold starts we get from Wasm, event-driven and time-sensitive workloads, such as webhooks, are an excellent fit for Fermyon Cloud. If you aren’t familiar, webhooks enable HTTP-based communication between two different APIs in an event-driven manner. Given we natively support HTTP triggers, we encourage developers to bring their creative webhooks to Fermyon Cloud.

To give you a bit of inspiration, let’s use this Spin GitHub webhook as an example. Every time our targeted GitHub repository receives a star or is forked, the Spin GitHub webhook pushes an update to our desired Slack channel to share information about the recent event.

An example Slack update from our Spin GitHub webhook

To build this webhook, we’ve used the Typescript/Javascript Spin SDK to handle incoming requests from the GitHub API and send the appropriate response to Slack. Below, you can see an example code snippet of the HTTP client in the handleStarEvent function. Visit our Language Support Overview document to learn more about language support with Spin and Fermyon Cloud.

import { HttpRequest, HttpResponse } from "@fermyon/spin-sdk";
import { StarCreatedEvent, StarDeletedEvent, ForkEvent, IssuesOpenedEvent, IssuesClosedEvent } from "@octokit/webhooks-types";
import { sendToSlack, Settings } from "./utils";

let decoder = new TextDecoder();

export async function handleStarEvent(req: HttpRequest, settings: Settings): Promise<HttpResponse> {
  let body = JSON.parse(decoder.decode(req.body));
  // Evaluate which event has transpired
  switch (body.action) {
    case "created":
      {
        let event = body as StarCreatedEvent;
        console.log(`Star created event from ${event.sender.login} for ${event.repository.full_name}. Star count ${event.repository.stargazers_count}.`);
        // Format Slack message title and text
        let title = `New star to repository ${event.repository.full_name} from ${event.sender.login}!`;
        let text = `:star:${event.sender.login} just starred your repository ${event.repository.full_name}!
The repository now has ${event.repository.stargazers_count} stargazers, see them all at https://github.com/${event.repository.full_name}/stargazers :star:!`;
        // Post message to Slack
        await sendToSlack(settings, title, text);
        return {
          status: 200
        }
      }

      // --snip--

Tip: While you can see the complete example on GitHub, if you’re interested in trying out the basics you can run spin new to get set up with a Spin Template that uses your preferred language alongside the HTTP trigger

Then, with the following three commands, we will build, login, and push our Spin webhook to Fermyon Cloud:

# Locally build and test your Spin app
spin build --up
Executing the build command for component spin-github-webhooks: npm run build

// --snip--

Serving http://127.0.0.1:3000
Available Routes:
  spin-github-webhooks: http://127.0.0.1:3000 (wildcard)
# Log into Fermyon Cloud
spin cloud login
Copy your one-time code:

xxxXXXXX

...and open the authorization page in your browser:

https://cloud.fermyon.com/device-authorization

Waiting for device authorization...
Waiting for device authorization...
Device authorized!
# Deploy your Spin app to Fermyon Cloud
spin cloud deploy
Uploading spin-github-webhooks version 0.1.0+rde3b9844...
Deploying...
Waiting for application to become ready............ ready
Available Routes:
  spin-github-webhooks: https://spin-github-webhooks-o7jecuug.fermyon.app (wildcard)

Hopefully, this has given you a good sense of a natural workload fit for Fermyon Cloud. With the above webhook example in mind, let’s take a look at the new Cloud features we’ve built and how we’d put them to use.

Pick Up The Speed: Bring Your CI/CD to Fermyon Cloud With GitHub Actions

Let’s fast-forward time a bit and imagine we’ve been using our Spin Slack webhook for some time now and users are asking for new functionality. Specifically, they’d find it useful if our Spin Slack webhook also updated the Slack channel when new issues were created and closed on the targeted GitHub repository. To help us quickly implement this feature, we’re going to set up a Continuous Deployment (CD) pipeline using fermyon/actions/spin/deploy GitHub Actions. This GitHub Action will automatically deploy our Spin application to Fermyon Cloud every time a pull request is merged. Now we can quickly and efficiently bring our local changes to Fermyon Cloud in an automated fashion that updates in lockstep with our development flow.

To get started, we’ll need to generate a Fermyon Cloud Personal Access Token (PAT) which will serve as the secret used to authenticate our deployment’s trigger by the spin/deploy GitHub Action.

Tip: For step-by-step instructions on how to accomplish this workflow, check out our GitHub Actions tutorial.

After plumbing the PAT as a repository secret and adding action.yaml to the Spin Slack webhook repository, we’re now ready to test out the CD functionality.

name: spin-deploy

// --snip--

    steps:

// --snip--

      - name: Setup `spin`
        uses: fermyon/actions/spin/setup@v1
        with:
          plugins: js2wasm

      - name: build and deploy
        uses: fermyon/actions/spin/deploy@v1
        with:
          manifest_file: spin.toml
          fermyon_token: ${{ secrets.FERMYON_TOKEN }}

Below you can see an excerpt of the function we’ll be adding to our webhook that supports issue events from GitHub.


// --snip--

// Simple HTTP component
export async function handleIssuesEvent(req: HttpRequest, settings: Settings): Promise<HttpResponse> {
  let body = JSON.parse(decoder.decode(req.body));
  // Evaluate which event has transpired
  switch (body.action) {
    case "opened":
      {
        let event = body as IssuesOpenedEvent;
        console.log(`${event.issue.user.login} just ${event.issue.state} Issue #${event.issue.number}:${event.issue.title}`);
        // Format Slack message title and text
        let title = `${event.issue.user.login} just opened Issue #${event.issue.number}:${event.issue.title}`;
        let text = `Check out the issue opened at ${event.issue.url} :mailbox_with_mail:`;
        // Post message to Slack
        await sendToSlack(settings, title, text);
        return {
          status: 200
        }
      } 

    // --snip--
    
  }
}

After testing the code locally with spin build --up, we’re ready to push the changes to Fermyon Cloud by committing and merging a pull request. You can see the GitHub Actions workflow has successfully completed, resulting in an updated Spin application being pushed to Fermyon Cloud.

A successful run for spin/deploy GitHub Action

Now users of our Spin Slack webhook can enjoy real-time updates on GitHub issues thanks to our quick delivery through GitHub Actions.

Example response from Slack webhook Issue Event Types

Let’s Get a Pulse on Activity: Implementing a Spin Application Request Count

As data-driven engineers, we’re curious to understand how frequently our Spin Slack webhook is being triggered by activity on the GitHub repository. Rather than having to scrape that information from Slack, we can now access a Spin application’s request count, over time, directly in the Cloud User Interface (UI). To check this out yourself, log into Cloud and click on your desired Spin application to view request count data.

Request Count Metric in Cloud UI

Every time a Spin’s HTTP trigger is invoked, the request count will increment accordingly. This gives us a sense of how active our Spin applications are, over a period of time. Each Spin application will populate the request count automatically; no setup required!

Summary

Well Fermyon friends, that’s it for now! We hope you enjoy trying out our GitHub Actions workflow and monitoring your application’s request count! Let us know what you think by reaching out via our Discord community and feel free to file Fermyon Cloud feature requests at Fermyon/Feedback.


🔥 Recommended Posts


Quickstart Your Serveless Apps with Spin

Get Started