GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - intility/reusable-elixir: Reusable workflows for Elixir apps

BranchesTags
Open more actions menu

Latest commit

 

History

294 Commits
294 Commits

Folders and files

NameName
Last commit message
Last commit date
.github
.github
 
 
CHANGELOG.md
CHANGELOG.md
 
 
CODEOWNERS
CODEOWNERS
 
 
CONTRIBUTING.md
CONTRIBUTING.md
 
 
LICENSE
LICENSE
 
 
README.md
README.md
 
 
example.yaml
example.yaml
 
 

Repository files navigation


Reusable Elixir Workflows

Opinionated reusable GitHub Actions workflows for Elixir projects. Ready workflows for testing, linting, static code analysis, documentation and building OCI compliant container images.

🔮 elixir-test

Runs tests and static analysis for Elixir projects.

Features

  • Parallel jobs for fast feedback (deps, audit, build, test, credo, dialyzer run concurrently)
  • Credo static code analysis, with results uploaded to GitHub code scanning (SARIF)
  • Dialyzer type checking with PLT caching
  • Sobelow security scanner (Phoenix)
  • PostgreSQL service container with Ash/Ecto support
  • SQLite support for Ash/Ecto
  • NPM install for Phoenix assets
  • Hex organization support for private packages

Usage

The examples use @main to keep them readable. Our org policy requires pinning uses: to a full commit SHA, so in your own workflows write @<sha> # vX.Y.Z with the SHA of the release you want. Dependabot keeps those pins up to date.

name: Test

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    # Uses .tool-versions from your project
    uses: intility/reusable-elixir/.github/workflows/elixir-test.yaml@main

Or specify versions explicitly:

jobs:
  test:
    uses: intility/reusable-elixir/.github/workflows/elixir-test.yaml@main
    with:
      elixir-version: "1.19"
      otp-version: "28"

For projects where the Elixir app lives in a subdirectory:

jobs:
  test:
    uses: intility/reusable-elixir/.github/workflows/elixir-test.yaml@main
    with:
      directory: apps/my-elixir-app
      postgres: ecto

Inputs

Name Type Default Description
directory string . Project directory (for subdirectory support)
elixir-version string - Elixir version (uses .tool-versions if not specified)
otp-version string - Erlang/OTP version (uses .tool-versions if not specified)
audit boolean true Run hex.audit and deps.audit
credo boolean true Run Credo static analysis
dialyzer boolean true Run Dialyzer type checking
sobelow boolean false Run Sobelow security scanner (Phoenix projects)
postgres string - PostgreSQL migrations: ash or ecto (starts service automatically)
postgres-image string postgres Docker image name without tag (e.g., timescale/timescaledb)
postgres-version string 18 Docker image tag for the postgres-image (e.g., 18, latest-pg18)
sqlite string - SQLite migrations: ash or ecto
npm-install boolean false Run npm install for assets
npm-working-directory string assets Directory for npm install
npm-registry string - Custom NPM registry URL (e.g., https://npm.pkg.github.com)
node-version string latest Node.js version
spark-formatter boolean false Check Spark DSL formatting
spark-extensions string - Spark DSL extensions for formatter (multiline, one per line)
hex-organization string - Hex organization for private packages
apt-packages string - Space-separated APT packages to install (e.g., libvips-dev)
env string - Environment variables for all jobs (one KEY=VALUE per line)
artifacts string - Multiline artifact definitions to download (name:path per line)
services string - Multiline YAML list of Docker sidecar services (see below)

Required Permissions

No permissions are required to run the workflow. To have Credo findings show up in GitHub code scanning (the Security tab and PR annotations), grant these in the calling workflow or job:

permissions:
  actions: read          # Private and internal repos only: the upload reads the workflow run
  contents: read
  security-events: write # Upload SARIF to code scanning

Private and internal repos also need GitHub Advanced Security (Code Security) enabled. Without these permissions, on pull requests from forks, or without Advanced Security, the upload is skipped or fails harmlessly. Credo findings fail the build either way.

Secrets

Name Required Description
hex-organization-key No Hex organization auth key
ssh-private-key No SSH private key(s) for private Git repository access
npm-token No NPM authentication token for private registries

Additional Services

Declare arbitrary Docker containers to run alongside your tests. Containers share a dedicated ci-services network, publish their ports on localhost, and are removed automatically when the job ends (including on failure).

jobs:
  test:
    uses: intility/reusable-elixir/.github/workflows/elixir-test.yaml@main
    with:
      postgres: ecto
      services: |
        - name: redis
          image: redis:7-alpine
          ports: 6379:6379
          health-cmd: redis-cli ping
        - name: mosquitto
          image: eclipse-mosquitto:2
          ports: 1883:1883
          volumes: $GITHUB_WORKSPACE/ci/mosquitto.conf:/mosquitto/config/mosquitto.conf:ro

Supported per-service fields: name (required), image (required), ports, env, volumes, options (raw docker run flags), health-cmd, health-timeout (seconds, default 60). Multi-value fields accept either a YAML sequence or a pipe-block scalar with one entry per line.

When health-cmd is set, the step waits for the container to report healthy before continuing. Without health-cmd, the caller is responsible for readiness (e.g. retrying in test setup).

Notes & limitations

  • options is a raw pass-through to docker run that word-splits on whitespace. Don't rely on embedded spaces in quoted values; use env: or volumes: for structured values.
  • Avoid --network and --name inside options; they override the action's own flags and break container isolation or naming. Extra --label flags are fine as long as reusable-elixir-ci=1 remains present so cleanup still matches.
  • On self-hosted runners shared by concurrent jobs, containers are labeled reusable-elixir-ci=1 regardless of which workflow started them. Parallel jobs using this feature on the same runner host can interfere during cleanup. GitHub-hosted runners (a fresh VM per job) are unaffected.

📚 elixir-docs

Builds and deploys Elixir documentation to GitHub Pages.

Usage

name: Docs

on:
  push:
    branches: [main]

jobs:
  docs:
    permissions:
      pages: write
      id-token: write
    uses: intility/reusable-elixir/.github/workflows/elixir-docs.yaml@main

Inputs

Name Type Default Description
elixir-version string - Elixir version (uses .tool-versions if not specified)
otp-version string - Erlang/OTP version (uses .tool-versions if not specified)
hex-organization string - Hex organization for private packages
apt-packages string - Space-separated APT packages to install (e.g., libvips-dev)
env string - Environment variables (one KEY=VALUE per line)
artifacts string - Multiline artifact definitions to download (name:path per line)

Secrets

Name Required Description
hex-organization-key No Hex organization auth key
ssh-private-key No SSH private key(s) for private Git repository access

📦 elixir-release

Important

This workflow expects your project to use the ocibuild library for building container images.

Builds and publishes Elixir releases as OCI container images or downloadable tarballs with supply chain security.

Features

  • Reproducible builds (opt-in) via SOURCE_DATE_EPOCH for consistent layer digests
  • Layer caching - unchanged layers (ERTS, deps) are skipped on upload
  • SLSA provenance attestation for supply chain security
  • Automatic OCI annotations (source URL, revision, version, created timestamp)
  • SBOM generation (Software Bill of Materials) included in images
  • Private Hex packages support via organization authentication
  • Multi-platform builds support (requires include_erts: false)
  • Release tarballs for deploying to regular servers (uploaded to GitHub Releases)

Usage

name: Release

on:
  push:
    tags: ["*"]
    branches: [main]

jobs:
  release:
    permissions:
      contents: read
      packages: write
      id-token: write
      attestations: write
    # Uses .tool-versions from your project
    uses: intility/reusable-elixir/.github/workflows/elixir-release.yaml@main
    with:
      source-date-epoch: "0" # Set mtime on all files in the archive to January 1, 1970 00:00:00 UTC to allow reproducible builds
    secrets: inherit

Release Tarballs

To build a release tarball and upload it to the GitHub Release instead of (or alongside) a container image:

jobs:
  release:
    permissions:
      contents: write       # Upload release assets
      id-token: write       # OIDC token for attestation
      attestations: write   # Create build provenance attestation
    uses: intility/reusable-elixir/.github/workflows/elixir-release.yaml@main
    with:
      docker: false
      tarball: true
    secrets: inherit

The tarball is named <name>-<version>-<os>-<arch>.tar.gz and includes a .sha256 checksum file. Both are uploaded as assets to the GitHub Release matching the current tag. The <os> and <arch> reflect the runner the workflow executes on (linux-amd64; the release job runs on ubuntu-24.04, so bundled ERTS needs glibc 2.39 or newer on the target); tarballs are single-architecture regardless of the platforms input, which only affects multi-arch OCI images.

For umbrella projects, or any project with multiple releases configured, set the release input to select which release to package. Single-release projects are detected automatically.

Note

The tarball input requires a GitHub Release to exist for the current tag. Use it with tag-triggered workflows or release-please. Re-running the workflow will overwrite previously uploaded assets with the same name.

Inputs

Name Type Default Description
directory string . Project directory
elixir-version string - Elixir version (uses .tool-versions if not specified)
otp-version string - Erlang/OTP version (uses .tool-versions if not specified)
hex-organization string - Hex organization for private packages
image-name string - Image name without registry prefix (e.g., my-app). Prefixed with ghcr.io/<owner>/. Defaults to repository name.
docker boolean true Build and push OCI image
tarball boolean false Build release tarball and upload to GitHub Release
base-image string - Override base image (e.g., elixir:1.19-slim)
platforms string - Multi-arch platforms (e.g., linux/amd64,linux/arm64)
release string - Release name if multiple configured
tags string semver + branch/pr Docker metadata tags
source-date-epoch string - SOURCE_DATE_EPOCH for reproducible builds (use 0 for layer caching)
assets-deploy boolean false Run mix assets.deploy to build and digest static assets
npm-install boolean false Run npm install and mix assets.deploy
npm-working-directory string assets Directory for npm install
npm-registry string - Custom NPM registry URL (e.g., https://npm.pkg.github.com)
node-version string latest Node.js version
apt-packages string - Space-separated APT packages to install (e.g., libvips-dev)
artifacts string - Multiline artifact definitions to download (name:path per line)

Secrets

Name Required Description
hex-organization-key No Hex organization auth key
ssh-private-key No SSH private key(s) for private Git repository access
npm-token No NPM authentication token for private registries
pull-username No Username for pulling base image (defaults to github.actor)
pull-password No Password for pulling base image (defaults to GITHUB_TOKEN)

Outputs

Name Description
digest The digest of the pushed OCI image (empty when docker is false)
tarball-name The filename of the uploaded tarball (empty when tarball is false)

Required Permissions

permissions:
  contents: read      # Checkout repository
  packages: write     # Push to GitHub Container Registry
  id-token: write     # OIDC token for attestation
  attestations: write # Create build provenance attestation

When using tarball: true, the contents permission must be write (instead of read) to upload release assets:

permissions:
  contents: write       # Upload release assets (use 'read' for docker-only)
  packages: write       # Push to GitHub Container Registry
  id-token: write       # OIDC token for attestation
  attestations: write   # Create build provenance attestation

Reproducible Builds & Layer Caching

Set source-date-epoch: "0" to enable reproducible builds and layer caching:

jobs:
  release:
    uses: intility/reusable-elixir/.github/workflows/elixir-release.yaml@main
    with:
      source-date-epoch: "0"

This ensures file timestamps are consistent across builds, enabling:

  • Layer caching - unchanged ERTS/deps layers keep the same digest and are skipped on upload
  • Reproducible builds - same source always produces the same image
  • Registry deduplication - identical content = identical digests

The actual build timestamp is recorded in the org.opencontainers.image.created annotation.


🔍 elixir-dependency-submission

Submits every Hex package in every mix.lock, transitive packages included, to the GitHub dependency graph.

GitHub's dependency graph does not read mix.lock, so Hex packages are missing from it. Dependabot only works on packages in the graph. This workflow finds every mix.lock that git tracks, parses it as text and submits the packages through the dependency submission API. Nothing is built or restored, and no repo code runs: the job only reads mix.lock and mix.exs files.

Usage

Run it on every push to main, and on a schedule so the snapshot stays current:

name: Dependency submission

on:
  push:
    branches: [main]
  schedule:
    - cron: "0 5 * * *"
  workflow_dispatch:

jobs:
  submit:
    permissions:
      contents: write # Used to submit the dependency snapshot
    uses: intility/reusable-elixir/.github/workflows/elixir-dependency-submission.yaml@main

The snapshot is attached to the commit that triggered the run, so only run it on the default branch.

Inputs

Name Type Default Description
directory string . Directory to search. Every mix.lock that git tracks below it is submitted, so a monorepo needs one call
correlator string hex-dependency-submission-<directory> Snapshot correlator. GitHub replaces a snapshot with a later one that has the same correlator

Behavior

  • Only public hexpm packages are submitted. Packages from a private Hex organization and Git dependencies are skipped, since a private package could share its name with a public one and match the wrong advisory.
  • A package is submitted as direct if it is listed as a {:name, ...} dependency in the mix.exs next to its mix.lock, and as indirect otherwise. For an umbrella (apps_path), the mix.exs of its apps count too. Other mix.exs files below the directory (other projects, fixtures, path dependencies) do not count. Dependencies built by a helper function are missed and show as indirect. Every package gets the runtime scope, since mix.lock does not record it.
  • All mix.lock files go into one snapshot, one manifest each. A lock with no public packages is skipped.
  • The run fails, before anything is submitted, if no mix.lock is found, none has public Hex packages, or a lock has entries it cannot parse. The snapshot replaces the previous one, so submitting the other locks would drop the alerts of the broken one. If a lock has no mix.exs next to it, or none of its packages appears in that mix.exs, the run warns and submits that lock's packages as indirect. Alerts match on name and version from the lock, so only the direct or indirect label is lost.

Pre-built Artifacts

For projects that depend on native binaries (Rust, Go, C) or other pre-compiled assets, you can inject artifacts from upstream jobs:

name: CI

on:
  push:
    branches: [main]

jobs:
  build-native:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: cargo build --release
        working-directory: native/cel_evaluator
      - uses: actions/upload-artifact@v4
        with:
          name: cel-evaluator
          path: native/cel_evaluator/target/release/cel_evaluator

  test:
    needs: [build-native]
    uses: intility/reusable-elixir/.github/workflows/elixir-test.yaml@main
    with:
      artifacts: |
        cel-evaluator:apps/my_app/priv/bin

  release:
    needs: [build-native, test]
    permissions:
      contents: read
      packages: write
      id-token: write
      attestations: write
    uses: intility/reusable-elixir/.github/workflows/elixir-release.yaml@main
    with:
      artifacts: |
        cel-evaluator:apps/my_app/priv/bin
    secrets: inherit

Multiple artifacts can be specified, one per line:

with:
  artifacts: |
    cel-evaluator:apps/my_app/priv/bin
    wasm-module:apps/my_app/priv/wasm

Note

GitHub artifact uploads strip POSIX file permissions. Handle this on your end (e.g., File.chmod/2 at runtime) rather than expecting executable bits to be preserved.


Complete Example

See example.yaml for a complete workflow using both test and release.

name: CI

on:
  push:
    tags: ["*"]
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    uses: intility/reusable-elixir/.github/workflows/elixir-test.yaml@main
    with:
      postgres: ash

  release:
    needs: test
    if: github.event_name != 'pull_request'
    permissions:
      contents: read
      packages: write
      id-token: write
      attestations: write
    uses: intility/reusable-elixir/.github/workflows/elixir-release.yaml@main
    with:
      source-date-epoch: "0"
    secrets: inherit

Version Management

elixir-test, elixir-docs and elixir-release take their Elixir/OTP versions from either a .tool-versions file or the elixir-version and otp-version inputs. A matrix is a way to feed those inputs; it is not a separate mechanism.

  • Neither input set: the project's .tool-versions is used.
  • Both inputs set: a .tool-versions is generated from them in the project directory on the runner, replacing any existing one for that run. Your committed file is not changed.
  • Only one input set: the run fails. elixir-version and otp-version must be given together.

Using .tool-versions (recommended)

If your project has a .tool-versions file, simply omit the version inputs:

jobs:
  test:
    uses: intility/reusable-elixir/.github/workflows/elixir-test.yaml@main
    # Uses versions from .tool-versions automatically

Example .tool-versions:

elixir 1.19.0
erlang 28.0

Using explicit versions

Specify both versions to override .tool-versions:

jobs:
  test:
    uses: intility/reusable-elixir/.github/workflows/elixir-test.yaml@main
    with:
      elixir-version: "1.19"
      otp-version: "28"

Matrix strategy for multiple versions

To test several Elixir/OTP combinations, pass the matrix values as the explicit inputs. Every entry must set both:

jobs:
  test:
    strategy:
      fail-fast: false
      matrix:
        include:
          # Elixir 1.18 supports OTP 25-27
          - elixir: "1.18"
            otp: "27"
          # Elixir 1.19 supports OTP 27-28
          - elixir: "1.19"
            otp: "27"
          - elixir: "1.19"
            otp: "28"
    uses: intility/reusable-elixir/.github/workflows/elixir-test.yaml@main
    with:
      elixir-version: ${{ matrix.elixir }}
      otp-version: ${{ matrix.otp }}

Note

When using a matrix, each combination spawns a separate workflow run with independent caching.


Private Hex Packages

For projects using private Hex organization packages:

jobs:
  test:
    uses: intility/reusable-elixir/.github/workflows/elixir-test.yaml@main
    with:
      hex-organization: intility
    secrets:
      hex-organization-key: ${{ secrets.HEX_ORGANIZATION_KEY }}

  release:
    needs: test
    uses: intility/reusable-elixir/.github/workflows/elixir-release.yaml@main
    with:
      hex-organization: intility
    secrets:
      hex-organization-key: ${{ secrets.HEX_ORGANIZATION_KEY }}

Private Git Dependencies

For projects with dependencies hosted in private Git repositories:

jobs:
  test:
    uses: intility/reusable-elixir/.github/workflows/elixir-test.yaml@main
    secrets:
      ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

  release:
    needs: test
    permissions:
      contents: read
      packages: write
      id-token: write
      attestations: write
    uses: intility/reusable-elixir/.github/workflows/elixir-release.yaml@main
    secrets:
      ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

Multiple keys are supported for accessing different repositories:

secrets:
  ssh-private-key: |
    ${{ secrets.REPO_A_DEPLOY_KEY }}
    ${{ secrets.REPO_B_DEPLOY_KEY }}

The SSH key(s) should have read access to your private repositories. You can combine this with Hex organization authentication if needed.

Private NPM Packages

For Phoenix projects with assets from private NPM registries:

jobs:
  test:
    uses: intility/reusable-elixir/.github/workflows/elixir-test.yaml@main
    with:
      npm-install: true
      npm-registry: https://npm.pkg.github.com
    secrets:
      npm-token: ${{ secrets.NPM_TOKEN }}

For GitHub Packages, you can use GITHUB_TOKEN:

secrets:
  npm-token: ${{ secrets.GITHUB_TOKEN }}

Database Support

PostgreSQL

Set postgres to start a PostgreSQL service and run migrations:

jobs:
  test:
    uses: intility/reusable-elixir/.github/workflows/elixir-test.yaml@main
    with:
      postgres: ash    # Ash Framework: ash_postgres.create + migrate
      # or
      postgres: ecto   # Ecto/Phoenix: ecto.create + migrate
      postgres-version: "18"  # Optional, defaults to 18

For PostgreSQL-compatible images (e.g., TimescaleDB), override the image name:

jobs:
  test:
    uses: intility/reusable-elixir/.github/workflows/elixir-test.yaml@main
    with:
      postgres: ash
      postgres-image: timescale/timescaledb
      postgres-version: latest-pg18

The service container image is built as {postgres-image}:{postgres-version}, defaulting to postgres:18.

SQLite

Set sqlite to run SQLite migrations (no service needed):

jobs:
  test:
    uses: intility/reusable-elixir/.github/workflows/elixir-test.yaml@main
    with:
      sqlite: ash    # Ash Framework: ash_sqlite.create + migrate
      # or
      sqlite: ecto   # Ecto: ecto.create + migrate

Phoenix Assets

For Phoenix projects using Mix-based asset tools (Tailwind, esbuild) without npm:

jobs:
  release:
    permissions:
      contents: read
      packages: write
      id-token: write
      attestations: write
    uses: intility/reusable-elixir/.github/workflows/elixir-release.yaml@main
    with:
      assets-deploy: true
    secrets: inherit

For Phoenix projects with JavaScript assets managed by npm:

jobs:
  release:
    permissions:
      contents: read
      packages: write
      id-token: write
      attestations: write
    uses: intility/reusable-elixir/.github/workflows/elixir-release.yaml@main
    with:
      npm-install: true
    secrets: inherit

Both options run mix assets.deploy before building the release. Use npm-install when your assets require npm ci first, or assets-deploy when your project uses Mix-managed tools like Tailwind and esbuild directly.

Environment Variables

For projects that need custom environment variables at compile time or test time (e.g., Cloak encryption keys):

jobs:
  test:
    uses: intility/reusable-elixir/.github/workflows/elixir-test.yaml@main
    with:
      env: |
        CLOAK_KEY=b23S/6av/mvyVEh27ksmXb+784i50afsp1FD0DUf87E=
        MY_OTHER_VAR=value

Environment variables are available in all jobs and all steps within the workflow.

Caching

The mix-cache composite action manages two independent caches:

  • Deps cache — the deps/ directory, keyed by .tool-versions and mix.lock
  • Build cache — the _build/<env> directory, keyed by .tool-versions, mix.lock, and source files

By default both caches are active. Jobs that only need dependencies (formatting, linting, auditing) can skip the build cache:

- uses: intility/reusable-elixir/.github/actions/mix-cache@main
  with:
    mix-env: test
    cache-build: "false"   # Only cache deps/
Input Type Default Description
mix-env string test MIX_ENV to cache for
cache-build string "true" Whether to cache _build/ (set "false" to skip)
directory string . Directory containing the Elixir project

The elixir-test workflow uses this internally — deps-only jobs skip the build cache so that build-test is the first to save it, and downstream jobs (test, dialyzer) restore the full build without recompiling.

Composite Actions

The workflows are built from lightweight composite actions in .github/actions/. These assume the environment is already set up (Elixir installed, deps cached) and can also be used independently in your own workflows.

Action Description
install-elixir Install Elixir and OTP via erlef/setup-beam using .tool-versions (supports directory)
mix-deps-get Install Hex, Rebar, and fetch dependencies (supports directory)
mix-compile Compile project (mix-env required, optional args, supports directory)
mix-task Run any mix task (task and mix-env required, supports directory)
mix-test Run mix test (mix-env required, supports directory)
mix-hex-audit Run mix hex.audit (supports directory)
mix-dialyzer Run Dialyzer with automatic PLT caching (mix-env required, supports directory)
mix-docs Compile and generate documentation (mix-env required)
mix-cache Cache deps/ and _build/ directories (supports directory)
setup-tool-versions Generate or use .tool-versions file (supports working-directory)
ssh-agent Set up SSH agent for private Git repositories
set-env Export environment variables from multiline input
apt-packages Install system packages via apt-get
download-artifacts Download workflow artifacts from multiline definitions (supports directory)
ocibuild Build and push OCI images

Using actions directly

steps:
  - uses: actions/checkout@v4
  - uses: intility/reusable-elixir/.github/actions/install-elixir@main
  - uses: intility/reusable-elixir/.github/actions/mix-cache@main
    with:
      mix-env: test
  - uses: intility/reusable-elixir/.github/actions/mix-deps-get@main
  - uses: intility/reusable-elixir/.github/actions/mix-compile@main
    with:
      mix-env: test
  - uses: intility/reusable-elixir/.github/actions/mix-task@main
    with:
      mix-env: test
      task: credo --strict

All actions support a directory input (default .) for monorepo projects:

steps:
  - uses: actions/checkout@v4
  - uses: intility/reusable-elixir/.github/actions/install-elixir@main
    with:
      directory: apps/my-app
  - uses: intility/reusable-elixir/.github/actions/mix-cache@main
    with:
      mix-env: test
      directory: apps/my-app
  - uses: intility/reusable-elixir/.github/actions/mix-deps-get@main
    with:
      directory: apps/my-app
  - uses: intility/reusable-elixir/.github/actions/mix-test@main
    with:
      mix-env: test
      directory: apps/my-app

Multi-Platform Builds

For multi-architecture images (requires include_erts: false in your release config):

jobs:
  release:
    uses: intility/reusable-elixir/.github/workflows/elixir-release.yaml@main
    with:
      base-image: "elixir:1.19-slim"
      platforms: "linux/amd64,linux/arm64"

Contributing

Contributions are welcome. Please read CONTRIBUTING.md for guidelines on reporting issues, submitting pull requests, and the overall project structure.


License

This project is licensed under the MIT License.

About

Reusable workflows for Elixir apps

Topics

elixirreusable-workflows

Resources

Readme
MIT license

Contributing

Contributing
Activity
Custom properties

Stars

1 star

Watchers

0 watching

Forks

0 forks
Report repository

Releases

Packages

Used by

Contributors

You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.