<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Joe Nash</title>
    <description>The latest articles on DEV Community by Joe Nash (@joenash).</description>
    <link>https://dev.to/joenash</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F50809%2Feaf93258-5255-4f2b-95f3-c89d1629dfc3.jpg</url>
      <title>DEV Community: Joe Nash</title>
      <link>https://dev.to/joenash</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/joenash"/>
    <language>en</language>
    <item>
      <title>Enso Dev Blog - 19th June 2020</title>
      <dc:creator>Joe Nash</dc:creator>
      <pubDate>Fri, 26 Jun 2020 12:18:30 +0000</pubDate>
      <link>https://dev.to/enso_org/enso-dev-blog-19th-june-2020-52da</link>
      <guid>https://dev.to/enso_org/enso-dev-blog-19th-june-2020-52da</guid>
      <description>&lt;p&gt;Welcome to the inaugural Enso devblog. In this series, we will share the latest updates from the development of Enso (formerly Luna), a visual language for data processing.&lt;/p&gt;

&lt;p&gt;Going forward, we’ll be sharing these updates at the end of each sprint, so you can expect an update every two weeks. This update is from the sprint ending on the 19th June 2020. If you want to keep up with the development of Enso in real time, you can follow along on &lt;a href="https://github.com/enso-org/enso"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  A new name for a new codebase.
&lt;/h1&gt;

&lt;p&gt;Luna is now Enso. Following a couple of years of going by Luna, we were facing issues that were making it difficult for us, and people looking for Luna. Luna is a popular term, and in programming-language land, is also very close to the popular language Lua, an endless source of confusion.&lt;/p&gt;

&lt;p&gt;Our new name, Enso, is inspired by the Japanese &lt;a href="https://en.wikipedia.org/wiki/Ens%C5%8D"&gt;円相&lt;/a&gt; (en-sō), “a circle that is hand-drawn in one or two uninhibited brushstrokes to express a moment when the mind is free to let the body create”. This concept elegantly captures what we are trying to achieve with our visual language, and is a guiding principle in ensuring that Enso is as intuitive, and natural to use, as possible.&lt;/p&gt;

&lt;p&gt;You can find us at our new home, &lt;a href="https://enso.org."&gt;https://enso.org.&lt;/a&gt; Whilst we continue rebranding, you may still see references to Luna here and there.&lt;/p&gt;

&lt;p&gt;As well as a new name, Enso has a completely new codebase. Luna 1.x, culminating in &lt;a href="https://github.com/enso-org/luna-archive"&gt;Luna 1.9&lt;/a&gt;, was a fantastic proof that what we set out to do is achievable. We were able to quickly validate the design of our dual representation visual language (where both the textual and visual versions of the workflow are equivalent and simultaneously updated), and confirm that many of the features we wanted to see in such a language, such as immutable data structures and currying, worked in the visual medium.&lt;/p&gt;

&lt;p&gt;Thanks to the participation of our community in using and contributing to 1.x, we were able to gather a huge amount of feedback, and points of improvement, including in areas of core language design. For example, the feedback from users of 1.x lead us to recognise the necessity of a feature we now call Uniform Call Syntax, which you can learn more about &lt;a href="https://dev.enso.org/docs/syntax/functions.html#universal-call-syntax"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So why start from scratch, and not continue to iterate on 1.9? The design decisions that allowed us to make those quick iterations proved to be detrimental to future progress. For example, the GUI was slow, based on SVGs, and integrated with the Atom editor. It would be difficult, if not impossible, to get the performance we wanted building on that foundation.&lt;/p&gt;

&lt;p&gt;Enso is a &lt;a href="https://github.com/enso-org/enso"&gt;complete rewrite&lt;/a&gt;, taking that validated design, and now focusing on performance and usability. Firstly, the new JIT compiler is built on &lt;a href="https://www.graalvm.org/"&gt;GraalVM&lt;/a&gt;, a &lt;a href="https://www.graalvm.org/docs/examples/java-performance-examples/"&gt;highly-performant Java VM&lt;/a&gt;. We are already seeing performance in some cases of 2 orders of magnitude faster than Python. The compilation process itself is also very fast, giving immediate feedback, particularly important in a visual language.&lt;/p&gt;

&lt;p&gt;The performance of the GUI is night and day compared to Luna 1.x, &lt;a href="http://github.com/enso-org/ide"&gt;rewritten from scratch with Rust&lt;/a&gt;, and compiled to WebAssembly. We’ve moved away from SVGs in Atom, to our own &lt;a href="https://github.com/enso-org/ide/tree/main/src/rust/ensogl"&gt;WebGL engine&lt;/a&gt;, heavily optimised to display 2D graphics, allowing for graphs built of thousands of nodes to run in 60 FPS. This engine will also power our new visualisations, displaying millions of points at 60 FPS.&lt;/p&gt;

&lt;p&gt;Thanks to GraalVM, we are also able to include some heavily demanded features. Enso will have a much bigger potential for foreign language interoperability — first with Java, but soon Python and R, bringing your existing data processing toolkit to Enso.&lt;/p&gt;

&lt;p&gt;We hope to publish a full article reflecting on our previous tech stack decisions, and why we’ve made the changes we have. But for now, let us show you what we’ve been working on.&lt;/p&gt;

&lt;h1&gt;
  
  
  Can I use Enso?
&lt;/h1&gt;

&lt;p&gt;Enso is currently pre-1.0, and is not ready for day to day data processing use cases. Most notably, there is currently no standard library. For now, intrepid adventurers can try out the latest builds via the artifacts in the GitHub repositories. You can find the instructions for getting and running Enso &lt;a href="https://dev.enso.org/docs/getting-enso.html#getting-enso"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Integrated Development Environment
&lt;/h1&gt;

&lt;p&gt;The &lt;a href="https://github.com/enso-org/ide"&gt;Enso IDE&lt;/a&gt; will include everything an end-user needs to process data with Enso. The IDE will support a user in writing both visual and textual Enso, with the tools and convenience expected from a modern IDE, such as auto-complete and context sensitive search.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nodes
&lt;/h2&gt;

&lt;p&gt;Users of Luna will notice that we’ve adopted a new node shape in Enso. Previously in Luna, the expression that defined a node would be displayed above the circular node, with the ports arranged along the outside of that circle. Now the node is the expression, and the input ports are the parameters of the expression.&lt;/p&gt;

&lt;p&gt;As Enso workflows are built from connecting these nodes, we’ve been putting a lot of work into making those connections as seamless, and pleasant as possible.&lt;/p&gt;

&lt;p&gt;Here you can see some of the new node and edge interactions:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AZs6jDXJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vmi5gqdzaytqj38elu0e.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AZs6jDXJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vmi5gqdzaytqj38elu0e.gif" alt="An output port from the first node is selected, and connected to the input port of another node."&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Creating edges from input nodes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f2hJciXB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/07fkz3si2pq7988ngtv3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f2hJciXB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/07fkz3si2pq7988ngtv3.gif" alt="An image showing two nodes connected by an edge. When hovering near the end of the edge on either node, the connection is highlighted, and clicking disconnects it from the nearest node."&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Disconnecting edges, with highlighting for the edge to be disconnected.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KwHzMHCX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hpl3broet91fpe8ozhmq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KwHzMHCX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hpl3broet91fpe8ozhmq.gif" alt="A node, when highlighted, reveals numerous output ports along its bottom edge."&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Support for many (MANY) output ports.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There is also some additional handling to prevent triggering a node interaction as you mouse around your canvas, say from one node to another. You may pass your mouse over another node. On a quick cursor over, the ports do not appear, requiring a longer interaction:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9v2xNIva--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lia5geq6stur37qophu8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9v2xNIva--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lia5geq6stur37qophu8.gif" alt="A node is moused over quickly, without triggering the display of ports. When the mouse lingers on the node, the ports render."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you add more nodes to your canvas, you’re going to want to move them around and organise them. Snapping makes that a breeze, helping you align graphs in your workflow:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--63J4eFOK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://user-images.githubusercontent.com/1790822/85856782-e3af3f80-b7b8-11ea-8dbe-906f2920c8f3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--63J4eFOK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://user-images.githubusercontent.com/1790822/85856782-e3af3f80-b7b8-11ea-8dbe-906f2920c8f3.gif" alt="A node remains stationary whilst another is snapped into various alignments around it"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Text editing
&lt;/h2&gt;

&lt;p&gt;Enso is dual representation, meaning the visual representation (nodes) are equivalent with a more traditional, textual programming language. Enso needs a text editor as beautiful and usable as its nodes.&lt;br&gt;&lt;br&gt;
This sprint, the Enso text editor got rich text display capabilities. It now supports colours per glyph, formatting such as bold, italics and strikethroughs, and widgets, such as sliders and cooler choosers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CWeXuzdn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/abifwmz3v01sqrr652b4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CWeXuzdn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/abifwmz3v01sqrr652b4.gif" alt="Text is displayed in red."&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Coloured text for future syntax highlighting.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The rendering engine has been integrated with the &lt;a href="https://github.com/xi-editor/xi-editor"&gt;Xi Editor rope-based backend.&lt;/a&gt; Thanks to Raph Levien and Trisan Hume from the Xi Editor team for all of their support and help!&lt;/p&gt;

&lt;h2&gt;
  
  
  Dual representation
&lt;/h2&gt;

&lt;p&gt;Numerous bugs in the module responsible for keeping the textual and visual representations in sync have been fixed, and support for runtime type information has been added. This change is not yet visible, but is a precursor to enabling support for types in the visual representation. Users of Luna may recall that ports and connections between nodes were coloured by the type of data they acted upon, which will now be possible in Enso.&lt;/p&gt;

&lt;p&gt;Dual representation correctly discovers nodes and connections, and updates the textual representation in real time as a user edits the node:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oMEc2u8A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0j1gw0xmsx06r3z214rz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oMEc2u8A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0j1gw0xmsx06r3z214rz.gif" alt="Nodes containing simple strings are updated in the text editor, causing the nodes to update. The nodes are then updated in the visual editor, causing the text to be updated."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Real-time updating between visual and textual representation.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project management
&lt;/h2&gt;

&lt;p&gt;Support for projects was added to the IDE, and it is now possible to open or create projects when invoking the IDE via the &lt;code&gt;--project&lt;/code&gt; argument:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gB2nRurC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vsmb7eov3b8km29zo7hb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gB2nRurC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vsmb7eov3b8km29zo7hb.gif" alt="Enso Studio is invoked from the command like with the --project flag to create a new project, and then to open an existing one."&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Invoking Enso Studio (the IDE) with the &lt;code&gt;--project&lt;/code&gt; argument to open existing projects.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Engine
&lt;/h1&gt;

&lt;p&gt;The Enso Engine includes the compiler, runtime and language server, and will, in the future, include the type checker. It is used as the backend of the Enso IDE, but can also be used in isolation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Language Server
&lt;/h2&gt;

&lt;p&gt;This sprint saw the start of support for auto-completion in the IDE added to the language server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D9Lgt1l5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6z416qz4sgkfo1q1jo9p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D9Lgt1l5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6z416qz4sgkfo1q1jo9p.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Auto-complete suggestions are obtained by querying the Semantic Database. The database is updated by extracting autocomplete entries from the compiled Enso workflow. The IDE holds its own view of the Semantic Database, by retrieving it from the server and subscribing for subsequent updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Language improvements
&lt;/h2&gt;

&lt;p&gt;Support for the type signature syntax was added. Whilst the signatures are not yet checked, initial support for suspended arguments has been added.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XkHC2ryT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0n36v4bc5r73msdjksvx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XkHC2ryT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0n36v4bc5r73msdjksvx.png" alt="A simple implementation of if then else in Enso, using suspended arguments specified in the type signature."&gt;&lt;/a&gt;&lt;br&gt;
Support for suspended arguments in type signatures.&lt;/p&gt;

&lt;p&gt;Booleans have been added to the language. These so-called “magic booleans” look like a &lt;a href="https://dev.enso.org/docs/syntax/types.html#type-definitions"&gt;normal datatype&lt;/a&gt;, but are actually well-optimised primitives under the hood.&lt;/p&gt;

&lt;p&gt;Check out these examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://github.com/luna/enso/blob/main/engine/runtime/src/test/scala/org/enso/std/test/BooleanTest.scala"&gt;https://github.com/luna/enso/blob/main/engine/runtime/src/test/scala/org/enso/std/test/BooleanTest.scala&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/luna/enso/blob/main/engine/runtime/src/test/scala/org/enso/std/test/NumberTest.scala%7D"&gt;https://github.com/luna/enso/blob/main/engine/runtime/src/test/scala/org/enso/std/test/NumberTest.scala&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Runtime
&lt;/h2&gt;

&lt;p&gt;Support for running “slow-path” Enso. As a functional language, Enso attempts to perform a variety of optimisations for function calls to ensure they are efficient, and easily inlined. However, there are cases, such as interpreter entry points and very polymorphic call sites, where caching and inlining would not be possible, taking too much time and memory. In this case, Enso takes the “slow-path”, which would be faster in those cases than attempting caching and inlining. You can learn more about “Megamorphic Call Sites” in the &lt;a href="https://dev.enso.org/docs/runtime/function-call-flow.html#megamorphic-call-sites"&gt;runtime docs.&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  More information
&lt;/h1&gt;

&lt;p&gt;That’s all for this developer update. We’ll be back with more after the next sprint. You can continue to follow along with Enso development on &lt;a href="https://github.com/enso-org/enso"&gt;GitHub&lt;/a&gt;, by joining our &lt;a href="https://discord.gg/enso"&gt;Discord server,&lt;/a&gt; or subscribing to updates on our &lt;a href="http://eepurl.com/g8Csr9"&gt;developer mailing list&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>datascience</category>
      <category>functional</category>
      <category>news</category>
    </item>
    <item>
      <title>Deploying to Heroku from GitHub Actions</title>
      <dc:creator>Joe Nash</dc:creator>
      <pubDate>Tue, 07 Jan 2020 22:12:20 +0000</pubDate>
      <link>https://dev.to/heroku/deploying-to-heroku-from-github-actions-29ej</link>
      <guid>https://dev.to/heroku/deploying-to-heroku-from-github-actions-29ej</guid>
      <description>&lt;p&gt;GitHub Actions give us a new way to deploy to Heroku, and to integrate Heroku with other parts of our development workflows. In a single GitHub Actions workflow, we could lint our Dockerfile and package configs, build and test the package on a variety of environments, compile release notes, and publish our app to Heroku. &lt;/p&gt;

&lt;p&gt;Today we are going to build a simple workflow that will use the Heroku CLI to deploy a project with a Dockerfile to Heroku via the &lt;a href="https://devcenter.heroku.com/articles/container-registry-and-runtime" rel="noopener noreferrer"&gt;Heroku Container Registry&lt;/a&gt;. During the course of building this workflow, we will see how to create jobs, configure the runner environment with GitHub secret store, use public actions, and react to and filter events. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is GitHub Actions?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt; are a way to trigger custom workflows in response to events on GitHub. For example, a push could trigger Continuous Integration (CI), a new issue being opened could trigger a response from a bot, or a pull request being merged could trigger a deployment. &lt;/p&gt;

&lt;h3&gt;
  
  
  Workflows, jobs, and actions
&lt;/h3&gt;

&lt;p&gt;Workflows are made up of jobs. These jobs are performed by a runner in a virtual environment. Jobs are composed of individual steps, and those steps can be scripts executed on the runner, or an action. Actions are composable units of workflows, that can be built in Docker containers or JavaScript, placed directly in your repository, or included via the GitHub Marketplace or Docker registry. &lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;To get started, push a project with a Dockerfile to GitHub, or &lt;a href="https://github.com/dockersamples/example-voting-app" rel="noopener noreferrer"&gt;fork an existing repository&lt;/a&gt;. Don’t forget that Heroku &lt;a href="https://devcenter.heroku.com/articles/container-registry-and-runtime#dockerfile-commands-and-runtime" rel="noopener noreferrer"&gt;provides an environment variable, &lt;code&gt;$PORT&lt;/code&gt;&lt;/a&gt;, for apps to bind to for HTTP traffic, so be sure to adjust the project to listen to that variable, rather than an explicitly set port. &lt;br&gt;
Within the repository, navigate to the Actions tab. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7yrnxw3tjbq1khvt5soa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7yrnxw3tjbq1khvt5soa.png" alt="A screenshot of the Actions tab within a new GitHub repository. Displayed is “Get started with GitHub Actions”, beneath which is the option to set up a simple starter workflow."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On first opening the Actions tab, we’ll be presented with some options for getting started. These include CI setups for popular languages, as well as a simple example workflow. Let’s start by selecting that simple workflow. Rename the file to &lt;code&gt;workflow.yml&lt;/code&gt;, and hit “Start commit”. &lt;/p&gt;
&lt;h3&gt;
  
  
  Your first workflow
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fn6my2po1waalrf8c6xxn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fn6my2po1waalrf8c6xxn.png" alt="A screenshot of the Code tab after selecting to set up a simple workflow. A code editor holds a simple workflow, repeated in the page below this image. A side bar explains the workflow and presents the option to commit it to the repository."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the workflow is setup, the repository will have a &lt;code&gt;.github/workflows&lt;/code&gt; folder, with a &lt;code&gt;workflow.yml&lt;/code&gt; file inside.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This workflow defines one job, &lt;code&gt;build&lt;/code&gt;, with 3 steps. One of those steps &lt;code&gt;uses&lt;/code&gt; an existing, public action, &lt;code&gt;checkout&lt;/code&gt;. The others are defined within the job, with a &lt;code&gt;name&lt;/code&gt;, and a &lt;code&gt;run&lt;/code&gt; field. &lt;code&gt;run&lt;/code&gt; executes commands on the runner performing the job. This job will use an Ubuntu machine. All GitHub Actions environments have the same specs, but you can run jobs on Ubuntu, MacOS, and Windows.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;checkout&lt;/code&gt; is an important action that you will use in most workflows that work on the code in the repository. &lt;code&gt;checkout&lt;/code&gt; fetches the contents of your repository to &lt;code&gt;$GITHUB_WORKSPACE&lt;/code&gt;, an environment variable that maps to &lt;code&gt;/home/runner/work&lt;/code&gt; on the runner. &lt;code&gt;checkout&lt;/code&gt;, like many first-party actions provided by GitHub, is open source and viewable on the &lt;a href="https://github.com/actions" rel="noopener noreferrer"&gt;Actions GitHub Organization&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;This workflow runs on the &lt;code&gt;push&lt;/code&gt; event, that is any time new contents are pushed to the repository. You can see the workflow and the status of its run under the Actions tab.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnisu45ni0neaqwulycx4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnisu45ni0neaqwulycx4.png" alt="A screenshot of the Actions tab after the workflow has been triggered. The actions tab shows the steps of the workflow having completed successfully with a green tick."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Inside the workflow, you can see that each of the named steps has logs that can be expanded. Naming and describing the steps in your workflows can help this interface provide rich information on the state of your deployments. &lt;/p&gt;

&lt;p&gt;Whilst the repository contents are fetched to the runner with &lt;code&gt;checkout&lt;/code&gt;, the workflow does not yet make any use of them. Let’s start working towards having this Dockerised project published to a Heroku app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Environment variables and GitHub Secret store
&lt;/h2&gt;

&lt;p&gt;You can deploy to the Heroku Container Registry with either &lt;a href="https://devcenter.heroku.com/articles/heroku-cli" rel="noopener noreferrer"&gt;the Heroku CLI&lt;/a&gt;, or Docker. Fortunately, &lt;a href="https://help.github.com/en/github/automating-your-workflow-with-github-actions/software-in-virtual-environments-for-github-actions" rel="noopener noreferrer"&gt;both are available within the virtual environment&lt;/a&gt; provided to the runners, when using Ubuntu. Using the Heroku CLI will give us access to other useful utilities, so let’s start there.&lt;/p&gt;

&lt;h3&gt;
  
  
  Browserless Heroku CLI Authorization
&lt;/h3&gt;

&lt;p&gt;In order to build or deploy, you will have to login to the Container Registry. When using the Heroku CLI locally, login is via the browser, but the Heroku CLI can also be authenticated by providing an OAuth token. &lt;/p&gt;

&lt;p&gt;To create an OAuth authorisation, on your local machine, run:&lt;br&gt;
&lt;code&gt;heroku authorizations:create&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This will create a long-lived user authorization, whose token can be used to authenticate the Heroku CLI in our workflow. &lt;/p&gt;

&lt;p&gt;The Heroku CLI expects this token to be found in an environment variable, &lt;code&gt;HEROKU_API_KEY&lt;/code&gt;. You can define environment variables within job steps, but you don’t want to insert the key directly and commit it to the repository. Luckily, GitHub Actions comes with a new Secrets store, within the repository settings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fn1l5crk1en3sa22i967s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fn1l5crk1en3sa22i967s.png" alt="A screenshot of the Secrets menu within the Settings tab of a GitHub repository. "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a prompt to add a new secret.&lt;/p&gt;

&lt;p&gt;Within Secrets, create a new secret, &lt;code&gt;HEROKU_API_KEY&lt;/code&gt;, and insert the token given by the Heroku CLI. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpymzh1ct5grmsa1wo7id.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpymzh1ct5grmsa1wo7id.png" alt="A screenshot of creating a new secret. There are two inputs, a name field, and a value field. The name filled is filled with  raw `HEROKU_API_KEY` endraw , and the OAuth token is to fill the value field."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Going back to our &lt;code&gt;workflow.yml&lt;/code&gt;, add a new step named “Login to Heroku Container Registry”. Within this step you need to define the environment variable &lt;code&gt;HEROKU_API_KEY&lt;/code&gt; by grabbing the secret, followed by running  &lt;code&gt;container:login&lt;/code&gt; with the Heroku CLI.&lt;/p&gt;
&lt;h3&gt;
  
  
  Workflow environment variables
&lt;/h3&gt;

&lt;p&gt;Environment variables are defined with &lt;code&gt;env&lt;/code&gt;. The workflow can access the contents of the repository secret store through a Context. There are many Contexts available which hold information about the workflow run, the job being performed, the runner environment, and the secret store. Retrieve the secret from the &lt;code&gt;secrets&lt;/code&gt; Context and assign it to an environment variable like so:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
 

&lt;p&gt;With that environment variable available, you can now run &lt;code&gt;heroku container:login&lt;/code&gt; to log into the Heroku Container Registry with the OAuth token.&lt;/p&gt;

&lt;p&gt;Commit that code and push it to the repository to trigger the workflow.&lt;/p&gt;

&lt;p&gt;Back under the Actions tab, your step will execute and log you in successfully:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fuqwqzyyjmodu80lqort7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fuqwqzyyjmodu80lqort7.png" alt="The Actions tab showing a green tick against every step of the job to login to Heroku Container Registry."&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Build and Release to Heroku Container Registry
&lt;/h2&gt;

&lt;p&gt;Now that the Heroku CLI is authenticated against the Heroku Container Registry, you can push your project to be built, and then release the resulting container. &lt;/p&gt;

&lt;p&gt;Create two new steps, one for the push, and the other for release. Each will also need a declaration of the &lt;code&gt;HEROKU_API_KEY&lt;/code&gt; environment variable, as environment variables are not persisted between steps. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;When pushing and releasing the container, you can specify an app name to target. This could be included safely in the workflow .yml, but as the app name is used in multiple commands, and you may want to change it later, let’s add it to the secret store and access it via the &lt;code&gt;secrets&lt;/code&gt; context.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Commit and push those changes, and return to the GitHub repository Actions tab to check on the build:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fh4wq6dz8ug6w03z13xmx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fh4wq6dz8ug6w03z13xmx.png" alt="The Actions tab showing a green tick against every step of the job to build and release to Heroku Container Registry. The Release step is expanded to show the output of the successful command."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The build has completed successfully, and you should now be able to visit your deployed app on Heroku.&lt;/p&gt;

&lt;h2&gt;
  
  
  Events and Filters
&lt;/h2&gt;

&lt;p&gt;Right now, the &lt;code&gt;push&lt;/code&gt; event is triggering this workflow, regardless of branch, or file, that new code is pushed to. You will likely want to tailor this trigger depending on your development practice. For example, if using the &lt;a href="https://guides.github.com/introduction/flow/" rel="noopener noreferrer"&gt;GitHub Flow&lt;/a&gt;, you may want to deploy to a staging environment when a pull request is merged to master. &lt;/p&gt;

&lt;p&gt;Workflow syntax gives us the ability to filter on branches, and files, as well as to trigger on all of the available &lt;a href="https://developer.github.com/webhooks/#events" rel="noopener noreferrer"&gt;GitHub webhook events&lt;/a&gt;. Let’s modify our &lt;code&gt;push&lt;/code&gt; event to filter only for pushes to &lt;code&gt;master&lt;/code&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Commit that, and push to master. Now any subsequent commits to branches other than &lt;code&gt;master&lt;/code&gt; will not trigger this workflow. &lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;You’ve now created a GitHub Actions workflow, that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On a push to &lt;code&gt;master&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Fetches the contents of the repository&lt;/li&gt;
&lt;li&gt;Logs into Heroku Container Registry&lt;/li&gt;
&lt;li&gt;Builds the container on Heroku&lt;/li&gt;
&lt;li&gt;Publishes the project to an Heroku app&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What’s next?
&lt;/h3&gt;

&lt;p&gt;From this workflow, you can add new steps, and jobs, for other tasks in your development process. For example, why not use the &lt;a href="https://github.com/marketplace/actions/docker-lint" rel="noopener noreferrer"&gt;Docker Lint&lt;/a&gt; action to lint the Dockerfile, before pushing to Heroku Container Registry?&lt;/p&gt;

&lt;p&gt;There are also other ways to implement Heroku in a GitHub Actions workflow. This example used the Heroku Container Registry, via the Heroku CLI already installed on the runner virtual environment. The &lt;a href="https://help.github.com/en/github/automating-your-workflow-with-github-actions/software-in-virtual-environments-for-github-actions" rel="noopener noreferrer"&gt;virtual environments also come with Git&lt;/a&gt;, so with minimal modification, you could use this workflow to &lt;a href="https://devcenter.heroku.com/articles/git" rel="noopener noreferrer"&gt;deploy projects without a Dockerfile&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>heroku</category>
      <category>devops</category>
      <category>tutorial</category>
      <category>github</category>
    </item>
  </channel>
</rss>
