> ## Documentation Index
> Fetch the complete documentation index at: https://timoni.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Module Distribution with GitHub Actions

> Publish module versions from GitHub workflows.

Timoni can be used in GitHub workflows to perform actions
such as build, test and push modules to container registries.

## Usage

To run Timoni commands on GitHub Linux runners,
add the following steps to your GitHub workflow:

```yaml theme={"system"}
steps:
  - name: Setup Timoni
    uses: stefanprodan/timoni/actions/setup@main
    with:
      version: latest # latest or exact version e.g. 0.13.0
  - name: Run Timoni
    run: timoni version
```

## Examples

### Push to GitHub Container Registry

Example workflow for linting, testing and pushing a module to GitHub Container Registry:

```yaml theme={"system"}
name: Release module
on:
  push:
    tags: ['*'] # semver format

permissions:
  contents: read # needed for checkout
  packages: write # needed for GHCR access

jobs:
  push:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Setup Timoni
        uses: stefanprodan/timoni/actions/setup@main
      - name: Vet module
        run: |
          timoni mod vet ./modules/my-module
      - name: Push module
        run: |
          timoni mod push ./my-module \
            oci://ghcr.io/${{ github.repository_owner }}/my-module \
            --version ${{ github.ref_name }} \
            --creds ${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}  
            --latest \
            -a 'org.opencontainers.image.licenses=Apache-2.0' \
            -a 'org.opencontainers.image.source=https://github.com/${{ github.repository }}' \
            -a 'org.opencontainers.image.description=My Timoni module.' 
```

### Push and sign with Cosign Keyless

Example workflow for pushing and signing the module using Cosign and GitHub OIDC:

```yaml theme={"system"}
name: Release and sign module
on:
  push:
    tag: ['*'] # semver format

permissions:
  contents: read # needed for checkout
  packages: write # needed for GHCR access
  id-token: write # needed for signing

jobs:
  push:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Setup Cosign
        uses: sigstore/cosign-installer@main
      - name: Setup Timoni
        uses: stefanprodan/timoni/actions/setup@main
      - name: Login to GHCR
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Vet module
        run: |
          timoni mod vet ./my-module
      - name: Push and Sign
        run: |
          timoni mod push ./my-module \
            oci://ghcr.io/${{ github.repository_owner }}/my-module \
            --version ${{ github.ref_name }} \
            --latest \
            -a 'org.opencontainers.image.licenses=Apache-2.0' \
            -a 'org.opencontainers.image.source=https://github.com/${{ github.repository }}' \
            -a 'org.opencontainers.image.description=My Timoni module.' \
            --sign=cosign
```

### Push to Docker Hub

Example workflow for using `docker login` to authenticate to Docker Hub:

```yaml theme={"system"}
name: Release module
on:
  push:
    tag: ['*'] # semver format

permissions:
  contents: read # needed for checkout

jobs:
  push:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Setup Timoni
        uses: stefanprodan/timoni/actions/setup@main
      - name: Login to Docker Hub
        uses: docker/login-action@v2
        with:
          registry: docker.io
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      - name: Vet module
        run: |
          timoni mod vet ./my-module
      - name: Push
        run: |
          timoni mod push ./my-module \
            oci://docker.io/my-org/my-module \
            --version ${{ github.ref_name }}
            --latest \
            -a 'org.opencontainers.image.licenses=Apache-2.0' \
            -a 'org.opencontainers.image.source=https://github.com/${{ github.repository }}' \
            -a 'org.opencontainers.image.description=My Timoni module.' 
      - name: Pull
        run: |
          mkdir -p /tmp/my-module
          timoni mod pull oci://docker.io/my-org/my-module \
            --version ${{ github.ref_name }} \
            --output /tmp/my-module
```

Note that [docker/login-action](https://github.com/docker/login-action)
can be used to authenticate to any private registry including ACR, ECR, GCR.
