Skip to content

Commit

Permalink
Provide self hosting flatpak repo docs
Browse files Browse the repository at this point in the history
  • Loading branch information
bbhtt authored and TingPing committed Dec 4, 2023
1 parent a3420e2 commit f0c31ed
Showing 1 changed file with 264 additions and 0 deletions.
264 changes: 264 additions & 0 deletions docs/hosting-a-repository.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,267 @@ of clicking the repository file or a download link that points to it.
the following command::

$ base64 --wrap=0 < key.gpg

Hosting a repository on Gitlab/Github pages
-------------------------------------------

Flat-manager can be complicated to self host. For single applications,
you can quickly host a Flatpak repository through Gitlab or Github pages
and distribute your app. These methods will rely on
`flatpak-github-actions <https://github.com/flatpak/flatpak-github-actions>`_.

.. note::
Github or Gitlab may have pipeline quotas, storage and bandwidth
limits. Please consult their documentation on this.

On Gitlab
^^^^^^^^^

The instructions will use Gitlab.com.

1. Create a new blank repository on Gitlab

2. Clone the repository locally

.. code-block:: bash
git clone git@gitlab.com:your_user_name/repo_name.git && cd repo_name
3. Create a ``.gitlab-ci.yml`` with the following contents.

.. code-block:: yaml
variables:
# Application id of the app, should be same as id used in flatpak manifest and appdata
APP_ID: tld.vendor.app_name
# Location of the flatpak manifest, root of git repository
MANIFEST_PATH: $CI_PROJECT_DIR/${APP_ID}.yaml
# Name of flatpak bundle
BUNDLE: "${APP_ID}.flatpak"
# Docker image to use
DOCKER_REGISTRY: "docker.io/bilelmoussaoui/flatpak-github-actions"
# Runtime to use, https://github.com/flatpak/flatpak-github-actions#docker-image
RUNTIME_NAME: "freedesktop"
# Runtime version to use
RUNTIME_VRESION: "23.08"
DOCKER_IMAGE: ${DOCKER_REGISTRY}:${RUNTIME_NAME}-${RUNTIME_VRESION}
SCHEDULE_TASK: default
stages:
- setup
- build
- deploy
# This will check for updates using external data checker and send PRs to the repo
update-sources:
stage: setup
image:
# https://github.com/flathub/flatpak-external-data-checker
name: ghcr.io/flathub/flatpak-external-data-checker
# Open shell rather than the bin
entrypoint: [""]
before_script:
- git config --global user.name "${GITLAB_USER_LOGIN}"
- git config --global user.email "${GITLAB_USER_EMAIL}"
script:
- /app/flatpak-external-data-checker --update --commit-only $MANIFEST_PATH
# Creates a merge request targetting the default repo branch and sets up auto merge when pipeline succeeds
- git push -o merge_request.create -o merge_request.target=${CI_DEFAULT_BRANCH} -o merge_request.merge_when_pipeline_succeeds
"https://${GITLAB_USER_NAME}:${CI_GIT_TOKEN}@${CI_REPOSITORY_URL#*@}" || true
artifacts:
paths:
- $MANIFEST_PATH
expire_in: 1 week
rules:
# Set up a pipeline schedule for this https://docs.gitlab.com/ee/ci/pipelines/schedules.html
- if: $CI_PIPELINE_SOURCE == "schedule" || $CI_PIPELINE_SOURCE == "trigger"
when: always
- when: never
flatpak:
stage: build
image: ${DOCKER_IMAGE}
variables:
# Stable Flathub repo
RUNTIME_REPO: "https://flathub.org/repo/flathub.flatpakrepo"
before_script:
# Sets up the stable Flathub repository for dependencies
- flatpak remote-add --user --if-not-exists flathub ${RUNTIME_REPO}
script:
# Sets up GPG signing
- gpg --list-keys --with-keygrip
- echo "allow-preset-passphrase" >> ~/.gnupg/gpg-agent.conf
- gpg-connect-agent reloadagent /bye
- cat $GPG_PASSPHRASE | /usr/libexec/gpg-preset-passphrase --preset $GPG_KEY_GREP
- gpg --import --batch ${GPG_PRIVATE_KEY}
# Build & install build dependencies
- flatpak-builder build --user --install-deps-from=flathub --gpg-sign=${GPG_KEY_ID} --disable-rofiles-fuse --disable-updates --force-clean --repo=repo ${BRANCH:+--default-branch=$BRANCH} ${MANIFEST_PATH}
# Generate a Flatpak bundle
- flatpak build-bundle --gpg-sign=${GPG_KEY_ID} repo ${BUNDLE} --runtime-repo=${RUNTIME_REPO} ${APP_ID} ${BRANCH}
- flatpak build-update-repo --gpg-sign=${GPG_KEY_ID} --generate-static-deltas --prune repo/
artifacts:
paths:
- repo
expire_in: 1 week
tags: [""]
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- when: always
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: always
- if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
when: manual
# Deploys the generated package to Gitlab pages name.gitlab.io/repo_name
pages:
variables:
BUILD_OUTPUT_PATH: ${CI_PROJECT_DIR}/repo
stage: deploy
image: alpine:latest
before_script:
- apk add rsync
# replace html assets relative path with pages absolute path
- find $BUILD_OUTPUT_PATH \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i -e "s#href=\"\/#href=\"$CI_PAGES_URL/#g" -e "s#src=\"\/#src=\"$CI_PAGES_URL/#g"
script:
- mkdir public || true
- rsync -av --exclude='public' --exclude='.git' $BUILD_OUTPUT_PATH/ public
artifacts:
paths:
- public
expire_in: 1 week
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: always
4. `Create <https://www.gnupg.org/gph/en/manual/c14.html>`_ a new GPG key
locally, to sign the repository.

5. Go to ``https://gitlab.com/-/profile/personal_access_tokens`` and create
a token for ``$CI_GIT_TOKEN``. Note that the token is valid for a
maximum of one year and you should renew it before it expires.

6. Go to ``https://gitlab.com/your_user_name/repo_name/-/settings/ci_cd``.
Expand `General` and disable public pipeline. Click Save.
Expand `variables`. Add the following
`variables <https://docs.gitlab.com/ee/ci/variables/#define-a-cicd-variable-in-the-gitlab-ciyml-file>`_
necessary for the pipeline to run:

.. list-table::
:widths: 15 20 25 15 15
:header-rows: 1

* - Type
- Key
- Value
- Protected
- Masked
* - Variable
- GPG_KEY_GREP
- Keygrip of GPG key
- Yes
- Optional
* - Variable
- GPG_KEY_ID
- Keyid of GPG key
- Yes
- Optional
* - File
- GPG_PASSPHRASE
- Passphrase of GPG Key
- Yes
- Optional
* - File
- GPG_PRIVATE_KEY
- ASCII armoured private key
- Yes
- Optional
* - Variable
- CI_GIT_TOKEN
- Token
- Yes
- Optional

To get the keygrip of the GPG key generated in step 4, run the
following in your terminal and look at the ``Keygrip`` section:

.. code-block:: bash
gpg --list-secret-keys --with-keygrip
To find the keyid of the GPG key run the following in the terminal. The
keyid should be in the first line starting with ``sec`` and
``algorithm/id``. The ``id`` part is the required keyid.

.. code-block:: bash
gpg --list-secret-keys --keyid-format=long
The following will generate an ASCII armoured private key. Then paste
the contents of that file in the CI variable settings.

.. code-block:: bash
gpg --output private.pgp --armor --export-secret-key <keyid or email>
7. Create a ``app_name.flatpakref`` in the root of the git repo with
the following contents.

.. parsed-literal::
[Flatpak Ref]
Title=<A pretty application or repo name>
Name=<Application id in tld.vendor.app_name format>
Branch=< branch of generated ostree refs, defaults to master>
Url=<Url of Gitlab page>
SuggestRemoteName=<A name for the flatpak remote>
Homepage=<URL of the homepage>
Icon=<Direct link to an icon>
RuntimeRepo=< Link to repo where runtime and other dependencies are eg. https://dl.flathub.org/repo/flathub.flatpakrepo>
IsRuntime=false
GPGKey=<base64 encoded GPG key>
You can find the Gitlab page in
``https://gitlab.com/your_user_name/repo_name/pages``. Disable
`Use unique domain` there and hit save. To generate the base64
encoded ``GPGKey``, run the following and paste the string:

.. code-block:: bash
gpg --export <keyid> > example.gpg
base64 example.gpg | tr -d '\n'
8. The root of the repository should contain the following
files: ``.gitlab-ci.yml``, ``app_name.flatpakref``, the flatpak manifest
``tld.vendor.app_name.yaml`` and any other files/folders referenced
in the manifest. ``git add`` these files, ``git commit`` and
``git push``.

9. If everything was set up correctly, the push will trigger the
pipeline to build and deploy your application with flatpak.

10. To install the build, you can run:

.. code-block:: bash
flatpak install --user https://gitlab.com/your_user_name/repo_name/-/raw/branch/app_name.flatpakref
This will set up a flatpak remote userwide, install the dependencies and
the application. Updates will be fetched when running ``flatpak update``
if they are available.

11. You can set up a `pipeline schedule <https://docs.gitlab.com/ee/ci/pipelines/schedules.html>`_,
optionally to automatically check for updates using
`flatpak-x-checker <https://github.com/flathub/flatpak-external-data-checker>`_
and send PRs to the repo.

Credits
^^^^^^^
The CI template is based on the `work <https://gitlab.com/accessable-net/gitlab-ci-templates>`_
of Flatpak community member
`proletarius101 <https://gitlab.com/proletarius101>`_.

0 comments on commit f0c31ed

Please sign in to comment.