Github for IT-ansatte

Denne siden er ment som en best practice guide til oppsett av konto og verktøy som skal brukes i kombinasjon med versjonskontroll gjennom github.uio.no. I første omgang beskrives bruk av 2-faktor og SSH/GPG-signering av commits for de repositoriene som krever dette. I tillegg er det lagt ved en best practice for hvordan man tar i bruk flere SSH-nøkler med samme bruker, da man ikke kan bruke systembrukere med github.uio.no, og måbruke deploy keys, som i github må være unike per repository.

Innholdsfortegnelse

Oppsett av 2-faktor autentisering

Alle ansatte ved USIT som skal bruke github.uio.no, må ha satt opp 2-faktor autentisering for deres bruker. For dette kan man bruke applikasjonene Microsoft Authenticator, Authy (Uten backup til cloud), Google Authenticator og EnPass på iOS og Android, eller FreeOTP på Android.

Etter at appen er nedlastet til mobilen kan man navigere til Github two factor authentication intro for å sette opp 2-faktor. Merk at 2-faktor i denne tjenesten ikke er avhengig/kompatibel med andre 2-faktortjenester ved UiO, så 2-faktor som blir satt opp i Github er kun brukbar i Github-tjenesten.

Merk at man skal bruke SSH-autentisering ved operasjoner mot Git-tjenesten, med andre ord at man bruker en SSH-nøkkel som er passordbeskyttet, da HTTP-autentisering i praksis blir 1-faktor autentisering.

Signere commits med SSH

Etter versjon 2.34.0 av git kan man signere commits med SSH-nøkler og dette er også støttet av github. Det er litt mindre omfattende enn å sette opp gpg da man som regel allerede har ssh-nøkler klare til bruk. Denne må legges inn på github spesifikt som signing key, deretter må man sette opp git til å bruke nøkkelen til å signere med.

I ~/.gitconfig bør følgende felter ha verdier (endre til ditt bruk)

[user]
	email = sjurher@usit.uio.no
	name = Sjur Hernes
	signingKey = /home/sjurher/.ssh/id_ed25519

[gpg]
	format = ssh
[commit]
	gpgsign = true

Import av SSH-nøkler til Github Actions runners

Man oppretter filen /opt/gh-runner-gpg/ssh_signers som eies av root:actions-runner med 750-rettigheter med innholdet av public key på dette formatet:

<epost i github> <innhold av public key>
eksempel@usit.uio.no ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJTULL/jlR82204TULLA11bA1dfCwbqyYr039x8LlmdM eksempel@usit.uio.no
eksempel@usit.uio.no ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJTULL/jlR82204TULLA11bA1dfCwbqyYr039x8LlmdM eksempel@usit.uio.no

Deretter sier man til git at git skal verifisere ssh-signerte commits med den fila i /home/actions-runner/.gitconfig den må eies av actions-runner

[gpg "ssh"]
	allowedSignersFile = /opt/gh-runner-gpg/ssh_signers

Man må også åppne i selinux for å gi ssh_keygen tilgang til filene som er opprettet av initrc i tmp når man importerer repoet når en jobb kjøres. Det kan enkelt gjøres ved å opprette filen /tmp/sshsign.te (merk at filnavn må være likt som modulnavn i fila)

module sshsign 1.0;

require {
	type initrc_tmp_t;
	type ssh_keygen_t;
	class file open;
}
allow ssh_keygen_t initrc_tmp_t:file open;

Deretter

sudo checkmodule -M -m -o /tmp/sshsign.mod /tmp/sshsign.te
sudo semodule_package -o /tmp/sshsign.pp -m /tmp/sshsign.mod
sudo semodule -i /tmp/sshsign.pp

Du skal nå være klar for å bruke SSH-nøkler med din github-actions-runner

Sette opp GPG på Windows

For Windows er det gpg4win som er anbefalt programvare for å bruke GPG-signering, og i tillegg forutsetter denne guiden at man har installert Git fra følgende nettside git-scm.com, installert med standard opsjonene valgt under installasjonen, blant annet git-bash, som brukes med gpg4win for konfigurasjon av gpg-nøkler og git i denne guiden. Gpg4win kan lastes ned fra gpg4win.org. Under installasjonen av gpg4win blir man spurt om hvilke komponenter man vil installere, og da holder det å installere GnuPG, de andre komponentene som Kleopatra etc. kan krysses vekk.

NB. Viktig at epostadressen du setter i din GPG-nøkkel samsvarer med primæradressen satt i din Github-bruker og på din klients git-config.

Etter at gpg4win er installert starter man opp git bash og skriver inn gpg --full-generate-key for å starte oppretting av GPG-nøkkel:

safet@DESKTOP-KJO66O8 MINGW64 ~
$ gpg --full-generate-key
gpg (GnuPG) 2.2.25-unknown; Copyright (C) 2020 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

gpg: directory '/c/Users/safet/.gnupg' created
gpg: keybox '/c/Users/safet/.gnupg/pubring.kbx' created
Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
  (14) Existing key from card
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? 5y
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: Safet Amedov
Email address: amedov@usit.uio.no
Comment:
You selected this USER-ID:
    "Safet Amedov <amedov@usit.uio.no>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: /c/Users/safet/.gnupg/trustdb.gpg: trustdb created
gpg: key F157AAAED0F88FEC marked as ultimately trusted
gpg: directory '/c/Users/safet/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/c/Users/safet/.gnupg/openpgp-revocs.d/2816B7AC83F167D94DBCB4B5F157AAAED0F88FEC.rev'
public and secret key created and signed.

pub   rsa4096 2021-01-12 [SC]
      2816B7AC83F167D94DBCB4B5F157AAAED0F88FEC
uid                      Safet Amedov <amedov@usit.uio.no>
sub   rsa4096 2021-01-12 [E]

Nå som du har en nøkkel generert, trenger du å hente ut public-delen av GPG-nøkkelen, som skal legges inn i Github. For det trenger du å hente ut keyID med følgende kommando:

$ gpg --list-secret-keys --keyid-format LONG
/c/Users/safet/.gnupg/pubring.kbx
---------------------------------
sec   rsa4096/F157AAAED0F88FEC 2021-01-12 [SC]
      2816B7AC83F167D94DBCB4B5F157AAAED0F88FEC
uid                 [ultimate] Safet Amedov <amedov@usit.uio.no>
ssb   rsa4096/F7AECB2A4DD9EA08 2021-01-12 [E]

KeyIDen du vil hente ut her er F157AAAED0F88FEC.

safet@DESKTOP-KJO66O8 MINGW64 ~/test4 (master)
$ gpg --armor --export F157AAAED0F88FEC
-----BEGIN PGP PUBLIC KEY BLOCK-----

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
=B5Qc
-----END PGP PUBLIC KEY BLOCK-----

Kopier hele PGP-keyblock'en, naviger til https://github.uio.no/settings/gpg/new og lim den inn i Key-feltet.

Den samme keyIDen skal brukes når du konfigurer din lokale git-klient til å bruke GPG-nøkkelen.

Sett følgende parametre for din git-klient. Merk at navn og epost må samsvare med det du har satt for din GPG-nøkkel:

git config --global gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"
git config --global user.signingkey F157AAAED0F88FEC
git config --global user.name "Safet Amedov"
git config --global user.email "amedov@usit.uio.no"
git config --global commit.gpgsign true

NB: Noen ganger må man bruke den lange keyIDen (git config --global user.signingkey 2816B7AC83F167D94DBCB4B5F157AAAED0F88FEC) dersom det ikke fungerer med den korte keyIDen.

Om du bruker Visual Code kan du enable signering i innstillingene slik: VS Code GPG

Du kan nå signere dine commits med din GPG-nøkkel, og arbeidsflyten er nesten helt lik som en vanlig git commit. Signering blir satt per repo med følgende kommando: git config commit.gpgsign true, og settes etter at du har navigert til repoet.

Deretter kan man legge til filer og commite til repositoriet som vanlig:

safet@DESKTOP-KJO66O8 MINGW64 ~/test4 (master)
$ touch foobar.txt

safet@DESKTOP-KJO66O8 MINGW64 ~/test4 (master)
$ git add foobar.txt
safet@DESKTOP-KJO66O8 MINGW64 ~/test4 (master)
$ git commit -m "ny fil"

Etter siste kommandoen vil man få en dialog fra Pinentry hvor man taster inn passordet til GPG-nøkkelen, som så brukes for å signere filen du nettopp har committet.

Filen er da signert, og man kan pushe den som vanlig til repositoriet

safet@DESKTOP-KJO66O8 MINGW64 ~/test4 (master)
$ git commit -m "ny fil"
[master ccf80da] ny fil
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 foobar.txt
safet@DESKTOP-KJO66O8 MINGW64 ~/test4 (master)
$ git push
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 2 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 891 bytes | 891.00 KiB/s, done.
Total 2 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To github.uio.no:amedov/test4.git
   09d77c5..ccf80da  master -> master

Sette opp GPG på Mac og Linux

For Linux kan man installere gpg med yum eller apt, alt etter som distroen du bruker.

NB. Viktig at epostadressen du setter i din GPG-nøkkel samsvarer med primæradressen satt i din Github-bruker og på din klients git-config.

Mac-spesifikt

For Mac-klienter kan man bruke GPGsuite, som kan lastes ned fra gpgtools.org. Det er også mulig å installere gpg med homebrew, men da bør man se seksjonen under for hvordan man omgår potensielle problemer med å få git og gpg til å spille sammen.

Problem med å få Git til å bruke GPG til å signere på Linux/Mac

Om man får følgende feilmelding, så skyldes dette at man ikke får en passord prompt fra GPG når man prøver å signere en commit med git:

error: gpg failed to sign the data
fatal: failed to write commit object

Workaround for dette er å putte følgende i .bash_profile:

export GPG_TTY=$(tty)

if [ -f ~/.gnupg/.gpg-agent-info ] && [ -n "$(pgrep gpg-agent)" ]; then
    source ~/.gnupg/.gpg-agent-info
    export GPG_AGENT_INFO
else
    eval $(gpg-agent --daemon --write-env-file ~/.gnupg/.gpg-agent-info)
fi

Når man installerer GPGsuite, vil det ved første oppstart be deg om å sette opp en GPG-nøkkel, men i denne guiden forutsettes det at man setter opp nøkkelen via kommandolinjen.

Oppsett for Linux og Mac


safetvm$  gpg --full-generate-key

gpg (GnuPG) 2.2.23; Copyright (C) 2020 Free Software Foundation, Inc.

This is free software: you are free to change and redistribute it.

There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:

   (1) RSA and RSA (default)

   (2) DSA and Elgamal

   (3) DSA (sign only)

   (4) RSA (sign only)

  (14) Existing key from card

Your selection? 1

RSA keys may be between 1024 and 4096 bits long.

What keysize do you want? (3072) 4096

Requested keysize is 4096 bits

Please specify how long the key should be valid.

         0 = key does not expire

      &lt;n&gt;  = key expires in n days

      &lt;n&gt;w = key expires in n weeks

      &lt;n&gt;m = key expires in n months

      &lt;n&gt;y = key expires in n years

Key is valid for? 5y

Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: Safet Amedov

Email address: amedov@usit.uio.no

Comment: GPG-key for github.uio.no

You selected this USER-ID:

    "Safet Amedov (GPG-key for github.uio.no) &lt;amedov@usit.uio.no&gt;"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O

We need to generate a lot of random bytes. It is a good idea to perform

some other action (type on the keyboard, move the mouse, utilize the

disks) during the prime generation; this gives the random number

generator a better chance to gain enough entropy.

We need to generate a lot of random bytes. It is a good idea to perform

some other action (type on the keyboard, move the mouse, utilize the

disks) during the prime generation; this gives the random number

generator a better chance to gain enough entropy.

gpg: key DBCE06BAA3D86117 marked as ultimately trusted

gpg: revocation certificate stored as '/Users/safet/.gnupg/openpgp-revocs.d/EFEA54DF5D118480843CBFE0DBCE06BAA3D86117.rev'

public and secret key created and signed.

pub   rsa4096 2021-01-11 \[SC\]

      EFEA54DF5D118480843CBFE0DBCE06BAA3D86117

uid                      Safet Amedov (GPG-key for github.uio.no) &lt;amedov@usit.uio.no&gt;

sub   rsa4096 2021-01-11 \[E\]

Nå som du har en nøkkel generert, trenger du å hente ut public-delen av GPG-nøkkelen, som skal legges inn i Github. For det trenger du å hente ut keyID med følgende kommando:

$ gpg --list-secret-keys --keyid-format LONG
/Users/safetvm/.gnupg/pubring.kbx
---------------------------------
sec   rsa4096/DBCE06BAA3D86117 2021-01-11 [SC]
      EFEA54DF5D118480843CBFE0DBCE06BAA3D86117
uid                 [ultimate] safet amedov <amedov@usit.uio.no>
ssb   rsa4096/8826246EB27700CC 2021-01-11 [E]

KeyIDen du vil hente ut her er DBCE06BAA3D86117.

$ gpg --armor --export DBCE06BAA3D86117
-----BEGIN PGP PUBLIC KEY BLOCK-----

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
=B5Qc
-----END PGP PUBLIC KEY BLOCK-----

Kopier hele PGP-keyblock'en, naviger til https://github.uio.no/settings/gpg/new og lim den inn i Key-feltet.

Den samme keyIDen skal brukes når du konfigurer din lokale git-klient til å bruke GPG-nøkkelen.

Sett følgende parametre for din git-klient. Merk at navn og epost må samsvare med det du har satt for din GPG-nøkkel:

git config --global user.signingkey DBCE06BAA3D86117
git config --global user.name "Safet Amedov"
git config --global user.email "amedov@usit.uio.no"
git config --global commit.gpgsign true

Du kan nå signere dine commits med din GPG-nøkkel, og arbeidsflyten er nesten helt lik som en vanlig git commit. Signering blir satt per repo med følgende kommando: git config commit.gpgsign true, og settes etter at du har navigert til repoet.

Deretter kan man legge til filer og commite til repositoriet som vanlig:

touch foobar.file
git add foobar.file
git commit -m "ny fil"

Etter siste kommandoen vil man få en dialog fra Pinentry hvor man taster inn passordet til GPG-nøkkelen, som så brukes for å signere filen du nettopp har committet.

Filen er da signert, og man kan pushe den som vanlig til repositoriet

safetvm@safetvms-Mac test4 % git commit -m "ny fil"
[master 09d77c5] ny fil
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 foobar.file
safetvm@safetvms-Mac test4 % git push
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 2 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 900 bytes | 900.00 KiB/s, done.
Total 2 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To github.uio.no:amedov/test4.git
   0f7d08a..09d77c5  master -> master

Hvordan brukere flere SSH-nøkler med samme bruker

Hvis en ønsker å hente ned repoer med upersonlige brukere, så er løsningen å legge til deploy keys på et repository. Merk da at det ikke er mulig å gjenbruke samme SSH-nøkkelpar over flere repoer som deploy keys i Github, da Github regner et SSH-nøkkelpar brukt i et reposistory som globalt unike.

I situasjoner hvor man skal hente ned flere repoer med upersonlige brukere, må man konfigurere dette på klientsiden. Nedenfor følger en relativt OS-agnostisk løsning på problemet.

For git-versjoner eldre enn 2.1

Denne er nok mest relevant for RHEL7-servere, da Windows-servere ikke er avhengig av git-versjon fra et gitt repo. For eldre versjoner kan en enten bruke enviroment-variabelen GIT_SSH til å sette hvilken nøkkel som skal brukes når en gjør en git-operasjon, eller så kan man gjøre det ved å lage custom hostnavninnslag i SSH-configfilen. Sistnevnte er anbefalt, da den første varianten forutsetter at man knoter med wrapperscript.

Gitt at du har to repoer, driftsrepo1 og driftsrepo2 så legger du inn følgende inn slag i .ssh/config:

Host driftsrepo1
    Hostname github.uio.no
    IdentityFile /home/driftsbruker/.ssh/driftsrepo1
    User git
Host driftsrepo2
    Hostname github.uio.no
    IdentityFile /home/driftsbruker/.ssh/driftsrepo2
    User git

Når man så skal klone repoet, så peker man på hostnavnet man opprettet over slik:

git clone driftsrepo1:ITI-BSD/driftsrepo1.git
Cloning into 'driftsrepo1'...
remote: Enumerating objects: 93, done.
remote: Total 93 (delta 0), reused 0 (delta 0), pack-reused 93
Receiving objects: 100% (93/93), 40.30 KiB | 0 bytes/s, done.
Resolving deltas: 100% (47/47), done.

Etter dette vil alle fremtidige operasjoner mot git bruke "driftsrepo1" som host. Dette kan bekreftes ved å ta en titt i .git/config i et gitt repo:

server $ cat .git/config
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "origin"]
        url = git@driftsrepo1:ITI-BSD/driftsrepo1.git
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
        remote = origin
        merge = refs/heads/master

Et par ting en bør ha i bakhodet om man velger å gå for ssh-configfil som løsning:

Beste workarounden er uansett å oppgradere til et OS som har nyere git, f.eks RHEL8.

For git 2.1 og nyere

Ved å sette følgende konfig i repoet en ønsker å utføre git-operasjoner med en gitt nøkkel, så vil den overstyre hvilken nøkkel git bruker for å utføre pull og push mot et gitt repo:

git config --local core.sshCommand "ssh -i /full/path/til/nøkkel"

Hvordan flytte repository fra Bitbucket og andre git-løsninger

I følgende eksempel skal vi flytte "migration_repo" fra Bitbucket til Github.

Opprett nytt repo i relevant organisasjon først. Ved å navigere til https://github.uio.no/organizations/IT-BSD/repositories/new, hvor du bytter ut IT-BSD med din organisasjon, så får du opp en nettside hvor du får lager et repo. Repoet som har blitt lagt til kalles migration_repo

Ved oppretting kan repoet kun være privat. Det det betyr er at om du vil at alle teams som er med i din organisasjon skal ha tilgang til repoet, setter du det til internal, hvis ikke setter du det til privat, og da må du selv spesifiere hvilke teams som skal kunne ha tilgang til repoet.

Merk at repoet per default kun har skrivetilgang for den som opprettet repoet, så selv for internale repoer må du definere hvem som skal ha mer enn lese-rettigheter på et gitt repo.

Neste er å endre remote url for repoet du ønsker å flytte. Dette forutsetter at du har klonet repoet til en klient/server, og har nyeste innholdet i repoet. Under ser man at jeg har bitbucket som remoteurl:

migration_repo server$git remote -v
origin	ssh://git@bitbucket.usit.uio.no:7999/bsd/migration_repo.git (fetch)
origin	ssh://git@bitbucket.usit.uio.no:7999/bsd/migration_repo.git (push)

Et repo kan ha flere remotes, så her må du tilpasse med tanke på ditt oppsett, men her tar vi utgangspunktet at vi kun skal endre på remote-konfigen origin. Under konfigurer jeg at ny remote skal peke på git@github.uio.no:IT-BSD/migration_repo.git:

migration_repo server$git remote set-url origin git@github.uio.no:IT-BSD/migration_repo.git
migration_repo server$git remote -v
origin	git@github.uio.no:IT-BSD/migration_repo.git (fetch)
origin	git@github.uio.no:IT-BSD/migration_repo.git (push)

Når det er gjort trenger man kun å kjøre git push --mirror, så vil alle filer, commits, remotes, tags og branches bli pushet opp til det nye repoet i Github:

migration_repo server$git push --mirror
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 206 bytes | 206.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To github.uio.no:IT-BSD/migration_repo.git
 * [new branch]      master -> master

Hvis du vil kun ha refs under refs/heads/ (som også inkluderer alle branches), bruker du git push --all.

Hvis du ikke ønsker å ta med alle branches, holder det å gjøre en vanlig git push

For å forhindre at noen fortsetter å pushe kode til det gamle repoet i Bitbucket, anbefales det å slette filene i bitbucket-repoet, og legge igjen en beskjed om at repoet er flyttet til Github.

Signering av commits

Signering av commits

Noen repoer krever at man signerer ens commits med GPG-nøkkel, for å autentisere innholdet i commiten. Det beste er at man signerer alle commits, og man kan sette dette som default med følgende innstilling:

git config --global commit.gpgsign true
git config --global user.signingkey = DIN_GPG_KEY_ID

Se guiden over for hvordan du henter ut DIN_GPG_KEY_ID.

Hvis du istedenfor ønsker å gjøre dette forskjellig fra repo til repo, eller commit til commit (ikke anbefalt metode), så kan du legge til -S når du gjør git commit, slik:

git commit -S

Rydde opp i usignerte commits

Hvis du faller i fristelse for å gjøre en commit uten signering, som viser seg å ha behov for signering, så kan du endre dette med følgende kommando:

git commit --amend -S

Om f.eks dine siste fire commits er usignerte, kan du endre dette med å rebase:

git rebase -i HEAD~4 --exec 'git commit --amend --no-edit --no-verify -S'

Import av GPG-nøkler til Github Actions runners

På våre Github Actions runnere, er det satt opp et script som sjekker hvorvidt en commit er signert med en kjent og gyldig GPG-nøkkel før Actions-jobber kjører. Om jobben ikke er signert med en kjent GPG-nøkkel, vil den feile. Løsningen da er at man importerer inn ens public GPG-nøkkel på runnerns GPG-store.

Nøklene ligger lagret under gh-runner-$RUNNERSERVER.uio.no:/opt/gh-runner-gpg/pubring.kbx. Alle eiere av en slik runner har tilgang til serveren med deres driftsbruker, og kan importere inn de GPG-nøklene som trengs.

Først hent ut og last opp GPG-nøkkelen:

gpg --armor --export dinepost@usit.uio.no| ssh bruker-drift@gh-runner-$RUNNERSERVER.uio.no "cat > ~/brukernavn.asc"

Deretter logg på serveren med din driftsbruker og kjør følgende kommando for å imnportere inn nøkkelen du nå har lastet opp:

sudo /opt/gh-runner-scripts/gpg-key-import.sh  ~/brukernavn.asc

Etter dette kan du enten lage en ny commit, eller trigge en re-run av jobben i Github Actions-fanen tilhørende repoet ditt.