Merging on GitHub Actions fails with “could not read Username for ‘https://github.com’: No such device or address”?

5 min read.

This article is going live 24th of December in 2024. That’s when we in Finland celebrate Christmas (yes – we celebrate on Christmas Eve, so that we can just chillax on Christmas day, either hungover, playing with our new toys, or both).

I’ll have you know I wrote this article a few days in advance. I’m definitely not working today – I’m frantically wrapping my wife’s presents or watching my kids unwrap some gifts I had no idea my wife got them, depending on whether you’re reading this as it goes live or a few hours later.

And if you’re reading it days, months or years afterwards, just feel free to enjoy the content! Happy holidays / Merry Christmas / Happy Hanukkah!


This article explains how to fix a failing GitHub Actions workflow, in which you’re trying to ninja-merge a branch to another one automatically.

Why? I mean… Maybe for like scheduled publishing of a site on GitHub pages? Or I don’t know, people have all kinds of weird and wild ideas, and apparently I’m not the first or the only one struggling with this.

But let’s take a step back. What am I doing and why?

Background

I wanted to have 2 branches – dev and main. Dev is going to get stuff committed or merged to it after approval, and will be merged to main on a schedule.

Not automatically, not on updates, preferably not manually – but nightly or weekly.

Having frantically googled this on Bing for quite a while, it turns out GitHub Actions doesn’t natively support scheduled merging. And I guess it doesn’t make sense in a lot of cases. But I wanted to make it work.

And after a bit of browsing, I did find this nice GitHub Actions workflow sample on StackOverflow.

name: Automerge
on:
  workflow_dispatch:
  schedule:
    # You can setup schedule here
    - cron: '0 0 * * *'
env:
  # replace "github_username" with your GitHub username
  # replace "github.com/username/repo.git" with your GitHub repo path
  # do NOT replace ${{secrets.GITHUB_TOKEN}}, GitHub will take care of it
  MY_REPO: https://github_username:${{secrets.GITHUB_TOKEN}}@github.com/koskila/myrepo.git
  # replace "long-lived_branch_name" with your branch name
  MY_BRANCH: main
  # replace it with the path to master repo
  MASTER_REPO: https://github.com/koskila/myrepo.git
  # replace "master" with your master branch name
  MASTER_BRANCH: dev
jobs:
  merge:
    runs-on: ubuntu-latest
    steps:
    - name: Merge with master
      run: |
        git clone ${{env.MY_REPO}} -b ${{env.MY_BRANCH}} tmp
        cd tmp
        git config user.name "Automerge Bot"
        git config user.email "bot@example.com"
        git config pull.rebase false
        git pull ${{env.MASTER_REPO}} ${{env.MASTER_BRANCH}}
        git push

Here I’m merging the dev (MASTER_BRANCH) of my repo (MASTER_REPO) to the main (MY_BRANCH) of, also, my repo (MY_REPO).

… I know the terminology gets a little bit messed up there. But that’s what you get when you copy-paste someone else’s homework, I guess 🤷

This is a pretty good starting point! But it doesn’t work.

Problem

I set it up with my branches, my repo, my desired nightly schedule and fired it off.

And it didn’t work.

Instead of a green disc, I got a red one. Usually not what you want.

Looking a bit closer, my error messages were somewhat like this:

Run git clone ***github.com/koskila/myrepo.git -b dev tmp
  git clone ***github.com/koskila/myrepo.git -b dev tmp
  cd tmp
  git config user.name "Automerge Bot"
  git config user.email "bot@example.com"
  git config pull.rebase false
  git pull https://github.com/koskila/myrepo.git main
  git push
  shell: /usr/bin/bash -e {0}
  env:
    MY_REPO: ***github.com/koskila/myrepo.git
    MY_BRANCH: dev
    MASTER_REPO: https://github.com/koskila/myrepo.git
    MASTER_BRANCH: main
Cloning into 'tmp'...
fatal: could not read Username for 'https://github.com': No such device or address
Error: Process completed with exit code 1.

Wait a minute…

fatal: could not read Username for ‘https://github.com’: No such device or address

That doesn’t sound good.

Reason

Ah well. As much as it pains me to admit it, the reason for this one was actually revealed by a StackOverflow answer, that was (as is typical and always so lovely to see on StackOverflow) downvoted because it was too helpful and friendly (I can only assume motivation, of course).

So the issue is that with the syntax/URI structure in the workflow you can not access a private repository.

Bah.

So instead of:

https://github_username:${{secrets.GITHUB_TOKEN}}@github.com/koskila/myrepo.git

I needed to use:

git@github.com:github_username/myrepo.git

But wait a minute… Where does it get the token, then?

Well. It does not. You can’t use the token to authenticate – instead, you need to set up SSH authentication for your GitHub Actions workflow.

Solution

Setting up an SSH authentication isn’t that complicated. Here are the steps.

1. Generate SSH private and public keys

Run this in terminal/PowerShell/your favorite shell:

ssh-keygen

You’ll get a couple of files in your .ssh directory with this – in my case, in directory C:\Users\<username>\.ssh\id_ed25519 I got the following files:

You might want to open both of them in VS Code (or some other text editor):

  • “File” – this is your private key
  • “.pub” – “Microsoft Publisher Document” – your public key

You’ll need both in just a sec.

2. Add your public key to your GitHub profile

Navigate to this URL: https://github.com/settings/ssh/new

You should see a field that says something like this: “Begins with ‘ssh-rsa’, ‘ecdsa-sha2-nistp256’, ‘ecdsa-sha2-nistp384’, ‘ecdsa-sha2-nistp521’, ‘ssh-ed25519’, ‘sk-ecdsa-sha2-nistp256@openssh.com’, or ‘sk-ssh-ed25519@openssh.com’

Copy your public key – from the file that ends with .pub – to this field, and save it.

Hit “Save” and you should now see something like this:

Great! On to the next step.

3. Add the private key to your repository

You’ll want to add it as a repository secret. Navigate to the “Settings” of your repository, and open “Secrets and variables” > “Actions”.

Under “Repository secrets” select “New repository secret”, create a new secret called “SSH_PRIVATE_KEY”, and copy the value from the file without a file extension.

Should look like this when you’re done:

Great. Now we’ll need to set it up in your workflow.

4. Get the SSH details from your repository

Open the “<> Code” -button and select “SSH” tab.

You should see something like below:

Copy the SSH url you can see.

5. Set up your worklow

Alright – finally, we’ll get to updating your workflow.

Add the following step before your git steps:

    - name: Setup SSH
      uses: webfactory/ssh-agent@v0.7.0
      with:
        ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

And change this:

MY_REPO: https://github_username:${{secrets.GITHUB_TOKEN}}@github.com/koskila/myrepo.git

To this:

MY_REPO: git@github.com:koskila/myrepo.git

(and note that you might have 2 different repository URLs – you need to change both!)

6. Run your GitHub Actions workflow again

With a bit of luck, you should have something like this:


Alright then. Did it work for you? Let me know in the comments below!

References

mm
0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
most voted
newest oldest
Inline Feedbacks
View all comments