This is the 12th day of my participation in the Gwen Challenge.More article challenges
Anything can get lost, unless you make a backup before you lose it! This article will show you how to use GitHub Actions to implement automatic backup repository.
The target
The goal of this article is to synchronize all repositories under GitHub user user-a to GitHub user user-b.
To prepare
Create a new code store with the following directory structure:
.├ ─.exercises ── workflows │ ├─Copy the code
And set three Secret in the code store, which are:
GH_TOKEN_A
Corresponds to a GitHub useruser-a
The AccessTokenGH_TOKEN_B
Corresponds to a GitHub useruser-b
The AccessTokenSLACK_WEBHOOK
Corresponding Slack WebHook address (optional)
workflow
Gets the code warehouse list
Use GitHub CLI gh to obtain all code storehouses under GitHub user-a
echo ${GH_TOKEN_A} > gh_token_a Write user-a's GitHub AccessToken to the file
gh auth login --with-token < gh_token_a # GitHub CLI login
gh repo list user-a -L 1000 > a_repos # fetch all the repository of user-a and write to the file
cat a_repos # display code store list
cat a_repos | wc -l # display the total number of code stores
Copy the code
Create a repository with the same name
Create a repository of the same name under GitHub user user-b.
gh repo create user-b/${repo_name} --private --description "${repo}" -y || true # Ignore error, code bin may already exist
Copy the code
Clone code store
Clone the GitHub repository under user-a with –bare.
git clone --bare https://${GH_TOKEN_A}@github.com/user-a/${repo_name}.git ${repo_name}
Copy the code
Push the code
The –all and –mirror parameters are used for code push respectively to prevent push failure due to too much data.
--all
Push all branches--mirror
According to pushrefs/
All references under, including branches, tags, and so on
cd ${repo_name}
mirror_repo="https://${GH_TOKEN_B}@github.com/user-b/${repo_name}.git"
git push --all -f ${mirror_repo} || true
git push --mirror -f ${mirror_repo} || true
Copy the code
To optimize the
- Ignore code silos that are too large or don’t require backup
In order to ensure the accuracy of the code warehouse name judgment, add oblique bars on the left and right sides of each code warehouse name when defining and judging
IGNORE_REPOS="/repo_a/repo_b/"
[[ ${IGNORE_REPOS}= ~"/${repo_name}/"&&]]continue || true
Copy the code
- for
tag
Too many code silos, backing up only branches
ONLY_BRANCH_REPOS="/repo_c/repo_d/"
[[ ${ONLY_BRANCH_REPOS}= ~"/${repo_name}/"&&]]continue || true
Copy the code
- Since the GitHub Actions time zone is
UTC
, timed task time required-8h
Monday to Friday at 2 a.m. :
- General configuration:
0, 2 times 1, minus 5
- GitHub Actions Scheduled tasks:
0, 18 times * 0, minus 4
Complete workflow configuration
. Making/workflows/mirror. Yaml files:
name: Mirror repos
on:
schedule:
- cron: "0 18 * * 0-4" Set up a scheduled task, Monday through Friday at 2am backup
workflow_dispatch: # Manually trigger the build
jobs:
mirror:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: GitHub CLI version
run: gh --version
- name: List repos
env:
GH_TOKEN_A: The ${{ secrets.GH_TOKEN_A }}
run: | echo ${GH_TOKEN_A} > gh_token_a gh auth login --with-token < gh_token_a gh repo list user-a -L 1000 > a_repos cat a_repos cat a_repos | wc -l
- name: Mirror repos
env:
GH_TOKEN_A: The ${{ secrets.GH_TOKEN_A }}
GH_TOKEN_B: The ${{ secrets.GH_TOKEN_B }}
IGNORE_REPOS: "/repo_a/repo_b/"
ONLY_BRANCH_REPOS: "/repo_c/repo_d/"
run: | echo ${GH_TOKEN_B} > gh_token_b gh auth login --with-token < gh_token_b
mkdir repos
cd repos
set -x
cat ${GITHUB_WORKSPACE}/a_repos | while read repo; do
repo_name=$(echo ${repo} | awk '{print $1}' | awk -F/ '{print $2}')
[[ ${IGNORE_REPOS} = ~ "/${repo_name}/" ]] && continue || true
gh repo create user-b/${repo_name} --private --description "${repo}" -y || true
rm -rf ${repo_name}
git clone --bare https://${GH_TOKEN_A}@github.com/user-a/${repo_name}.git ${repo_name}
cd ${repo_name}
mirror_repo="https://${GH_TOKEN_B}@github.com/user-b/${repo_name}.git"
git push --all -f ${mirror_repo} || true
[[ ${ONLY_BRANCH_REPOS} = ~ "/${repo_name}/" ]] && continue || true
git push --mirror -f ${mirror_repo} || true
cd -
done
- name: Slack Notification
uses: rtCamp/action-slack-notify@v2
env:
SLACK_WEBHOOK: The ${{ secrets.SLACK_WEBHOOK }}
Copy the code