'Crontab GitHub push won't recognize credentials

I have a crontab script to push some files to git. I use github desktop and it created my directory on my M1 MacOs computer.
Shell Script:

#!/bin/sh
cd /Users/me/Documents/GitHub/myUsername.github.io
git add -A
git commit -m "Daily update."
git push

The script works just fine when I run it from terminal but when I run it via chron I get the message

fatal: could not read Username for 'https://github.com': Device not configured

How can I run this from crontab and have it successfully push?



Solution 1:[1]

Check if the process runs as root from cron.

If so, it would not access the same git config --global credential.helper setting (which is set in /home/myuser, not /root)

Make sure your crontab file uses the username field in order to execute the command as you, not as root.

The OP confirms:

  • the process is runs as the user account
  • there is no credential helper.

Recommendation:

  • install GCM, the cross-platform Git Credential Manager from Microsoft
  • register your github.com credentials (GitHub user account / token)

That is:

printf "host=github.com\nprotcol=https\nusername=MyGitHubAccount\npassword=myGitHubToken" | git credential-manager-core store

This assumes the git-credential-manager-core executable installed with GCM is in your $PATH.

That way, no more "could not read Username" on the next git push.


The OP Sparkles adds in the comments:

It turned out I do think homebrew was affecting things because after getting rid of it it all seemed to work.

Solution 2:[2]

You can use dictionary comprehension and slicing for that

lst= [[country,usa,uk,india,japan],
[city,tokyo,berlin,moscow,abudhabi],
[planet,earth,mars,venus]]

result = [{l[0]:l[1:]} for l in lst]

here I have assumed that lst is a list of lists you want to create a list of dictionaries from it. This was not 100% clear from you question.

Solution 3:[3]

I am assuming that you did not use strings and the list you gave was not a nested list so I modified the code based on my understanding of your code.

The list is defined by

lst= [['country','usa','uk','india','japan'],
['city','tokyo','berlin','moscow','abudhabi'],
['planet','earth','mars','venus']]

to convert it to a dictionary I used

dict={lst[0][0]:lst[0][1:5],
      lst[1][0]:lst[1][1:5],
      lst[2][0]:lst[2][1:4]}

and this is what printing the dictionary looks like

{'city': ['tokyo', 'berlin', 'moscow', 'abudhabi'],
 'country': ['usa', 'uk', 'india', 'japan'],
 'planet': ['earth', 'mars', 'venus']}

Solution 4:[4]

Assuming this valid python input:

lst = [['country','usa','uk','india','japan'],
       ['city','tokyo','berlin','moscow','abudhabi'],
       ['planet','earth','mars','venus']]

Use zip, and the dict constructor:

keys, *vals = zip(*lst)
d = dict(zip(keys, map(list,vals)))

Output:

{'country': ['usa', 'uk', 'india', 'japan'],
 'city': ['tokyo', 'berlin', 'moscow', 'abudhabi'],
 'planet': ['earth', 'mars', 'venus']}

Solution 5:[5]

Assuming this is the input you want:

lst = [['country','usa','uk','india','japan'],
       ['city','tokyo','berlin','moscow','abudhabi'],
       ['planet','earth','mars','venus']]

and the output is a single dictionary like this:

{'country': ['usa', 'uk', 'india', 'japan'], 'city': ['tokyo', 'berlin', 'moscow', 'abudhabi'], 'planet': ['earth', 'mars', 'venus']}

You can use dict comprehension with list unpacking to get the result:

mydict = {k: vals for (k, *vals) in lst}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Simon Hawe
Solution 3 Kensac
Solution 4
Solution 5 Lukasz Wiecek