Due to the limitation of git you cannot have a repository inside another with it both modified and uploaded but don’t affect the upstream. It happens that the inner repo does not belong to you but you want to keep it up-to-date with GitHub Actions but still maintain the ability to modify it, here is the solution.

Mirror the theme

It doesn’t mean we can skip or fix the limit of git, but we can find a way to avoid that. Since there may be sensitive informations in your theme’s config, it is not recommended to directly fork the repo. Instead, create a new repo at GitHub and mirror the theme repo like below:

1
2
3
4
5
git clone --bare https://github.com/exampleuser/the-theme-repo.git
cd the-theme-repo.git
git push --mirror https://github.com/your_github_id/new-repository.git
cd ..
rm -rf the-theme-repo.git

Now you have the full permissions to make modifications to it. With your changes all done, commit and push them to the cloud.

Use ssh-keygen -t ed25519 -b 4096 -C "$(git config user.email)" -f github-deploy-key to generate a key pair for the workflow to update the theme repo automatically, hit enters. Don’t put passphrases, or there can be problems for Actions to use it. Make sure you do not upload your key pair to the cloud.

Open your theme repo, paste the content of the public key github-deploy-key.pub to its Deploy keys section in settings:

Deploy keys

Naming doesn’t matter, but you might want to give it a good name if you don’t want to mess it up in the future.

Update Hexo Directory

Since the theme is now saved in the cloud, we no longer need locally. Remove it, commit, add themes/ to .gitignore, commit again.

Add the private key you just created github-deploy-key to the Secrets section in settings of your blog repo:

Secrets

I used THEME_UPDATE_PRIV_KEY here, you can use your own name, but remember to change the workflow accordingly.

Update GitHub Actions workflows

Here comes the important part, let’s update the workflow to do the following things:

  • git clone your fork of the theme
  • check for updates in the upstream
  • update your fork on any changes
  • build and upload your blog as we did in my previous post

Take the following workflow as a reference:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
name: CI
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@main
with:
persist-credentials: false
- name: Update Themes
run: |
mkdir -p ~/.ssh/
echo "${{ secrets.THEME_UPDATE_PRIV_KEY }}" > ~/.ssh/id_rsa # change the secret name accordingly
chmod 600 ~/.ssh/id_rsa # put your private key to id_rsa so it can be used to access the repo
ssh-keyscan github.com >> ~/.ssh/known_hosts # add the known_hosts to avoid user input
git config --global user.email "your@email.tld"
git config --global user.name "your_github_id" # not mandatory but recommended
git clone git@github.com:your_github_id/new-repository.git themes/theme_name # SSH is mandatory, https doesn't work with our keys
pushd themes/theme_name # go to the theme dir
git remote add upstream git://github.com/exampleuser/the-theme-repo.git
git fetch upstream # set upstream
git pull upstream master # check updates
git push origin master # if everything's fine, upload the changes to your fork
popd
- name: Use Node.js ${{ matrix.node_version }}
uses: actions/setup-node@main
with:
node-version: ${{ matrix.node_version }}
- name: Cache node_modules
uses: actions/cache@main
env:
cache-name: hexo-node-modules
with:
path: node_modules
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('package-lock.json') }}
- name: Cache workers-site/node_modules
uses: actions/cache@main
env:
cache-name: workers-site-node-modules
with:
path: workers-site/node_modules
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('workers-site/package-lock.json') }}
- run: npm i
- run: npm run build
- name: Deploy to Cloudflare Workers
uses: cloudflare/wrangler-action@master
with:
apiToken: ${{ secrets.CF_WORKERS_TOKEN }}

You can find the only changes happen is the new Update Themes block, details have been added as comments. If the upstream changes do not affect your own changes, the workflow should finish by itself and everything’s fine. But if there is something wrong with you files, a merge failure will come up and fail the workflow as well. You will receive an email from GitHub notifying you about that, and you can fix the conflicts manually. Before that, nothing on your blog will be changed.

References