Recuperar archivos de otro repositorio privado de tu organización desde GitHub Actions

Esta semana se me planteó un escenario donde era necesario recuperar desde un flujo de GitHub Actions archivos que se encontraban en otro repositorio privado dentro de la misma organización de GitHub. En este artículo te cuento cómo hacerlo haciendo uso de una GitHub App.

Repositorio donde están los archivos que necesito

Para este ejemplo me he creado un repositorio llamado configurations donde solamente tengo un archivo llamado test.txt que, en teoría, tiene la información que necesito consumir desde el repo donde lanzaré el flujo con GitHub Actions.

Repositorio privado donde están los archivos que necesito

Como puedes ver, este es privado por lo que necesito estar autenticado para poder hacer un checkout de tu contenido.

Crear una GitHub App

Para poder interactuar con el repositorio al que quiero acceder necesito un token. Lo ideal es no tener que usar un Personal Access Token (PAT), ya que estos están asociados a usuarios y en este caso va a ser un flujo de GitHub Actions el que de manera automática lo va a usar. Para este tipo de escenarios podemos usar una GitHub App. Para crearla, dentro de tu organización debes ir al apartado Settings > Developer settings > GitHub apps. y en él hacer clic en el botón New GitHub app.

Crear una nueva GitHub App

En la configuración de esta debes elegir un nombre para la misma (en mi caso config-app), una URL de la aplicación a la que representa (puede ser cualquiera), desactivar el check de la opción Active del apartado WebHook y, lo más importante, los permisos que tendrá esta allá donde se instale. Para este ejemplo solo necesitamos el permiso Read only para el apartado Contents.

Desactiva el check de WebHook y Read-only para Contents

Si necesitas ser más estricto en tu escenario, también puedes dar permisos sobre un solo archivo usando el apartado Single file y poniendo la ruta de dicho elemento.

Una vez generada, copia el valor de App ID y haz clic en el enlace generate a private key:

En el siguiente apartado, solamente tienes que pulsar el botón y te descargará de manera automática un archivo *.pem donde tendrás la clave privada que usaremos después.

El último paso que necesitas para que estos permisos se correspondan con el repositorio de origen, es acceder al apartado Install App y seleccionar la organización donde está el repositorio.

GitHub – Install App

Podrías aplicar esta aplicación con estos permisos a todos los repositorios de la organización. Sin embargo, en mi ejemplo solo elijo aquel donde realmente lo necesito.

Instalar la aplicación solo en el repo configurations

Repositorio desde el que quiero acceder a los archivos de configurations

Por el otro lado, tengo un repositorio donde tengo configurado un workflow con GitHub Actions desde el cual quiero ser capaz de acceder al contenido del repositorio configurations. Para ello voy a utilizar la GitHub App, que me ayudará a conseguir un token que me permita cumplir mi objetivo. En el apartado Secrets de dicho repositorio crea dos: uno llamado APPLICATION_ID, que tendrá como valor el App ID de mi GitHub App, y APPLICATION_PRIVATE_KEY, donde copiaré el contenido del archivo *.pem que se descargó cuando generé la clave privada para la aplicación.

Para poder probar esta configuración, he creado un flujo bastante simple:

name: Get files from other repo demo

on:
  push:
    branches: [main]
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/[email protected]
        with:
          path: main
      - name: Get Token
        id: get_workflow_token
        uses: peter-murray/[email protected]
        with:
          application_id: ${{ secrets.APPLICATION_ID }}
          application_private_key: ${{ secrets.APPLICATION_PRIVATE_KEY }}
      # Get files from other private repo in your org
      - name: Get files from other repo
        uses: actions/[email protected]
        with:
          ref: main
          repository: returngis/configurations
          token: ${{ steps.get_workflow_token.outputs.token }}
          path: configurations
      - name: Echo file from configurations repo
        run: cat configurations/test.txt       

En él, utilizando la acción de Peter Murray, recupero el token gracias a mi GitHub App, uso la acción checkout con el nombre del repo, el branch, la ruta donde quiero dejar el contenido y el token obtenido en el paso anterior. Por último, con un cat muestro el contenido del archivo que deberíamos de haber conseguido si todo ha ido correctamente.

Antes de lanzar el flujo necesitas instalar tu GitHub App en este repositorio, al igual que hiciste con el de configurations:

La aplicación config-app también tiene que estar instalada en el repo de destino

ya que de lo contrario obtendrás un error como el siguiente:

Si has seguido todos los pasos, deberías de poder ver el contenido del archivo descargado de configurations:

Recuperando archivos de otro repositorio privado desde GitHub Actions

¡Saludos!