Skip to content

Contributing to DaxLib

How to contribute a Library to DaxLib


Dax Lib, a centralized repository of DAX UDF libraries, has just announced a new type of library - Medium/Large. I will show the processes of how to submit a Small library, then how to move from a Small to Medium/Large library, and explore why you might want to do this.

Small libraryΒΆ

In this mode you develop your library on a personal fork of daxlib/daxlib (i.e evaluationcontext/daxlib), then submit a pull request to daxlib/daxlib to submit your library, and your library will be released to Dax lib. There is a guide on how to contribute a small library to DAX Lib.

The process is as follows:

sequenceDiagram
    participant DaxLib as daxlib.org
    participant Main as daxlib/daxlib
    participant Fork as evaluationcontext/daxlib

    Main->>Fork: 1. Fork repository
    Fork->>Fork: 2. Develop library
    Fork->>Main: 3. Submit pull request
    Main->>Main: 4. Review & merge
    Main->>DaxLib: 5. Package deployed
  • Go to daxlib/daxlib github repo, and create a fork
  • Create a folder within packages, for your library, and add/update the relevant files
daxlib/daxlib package

The example below shows the structure of the daxlib/daxlib repo, showing only the relevant items

└── πŸ“ packages
    |── πŸ“ a   
    β”œβ”€β”€ πŸ“ ...
    β”œβ”€β”€ πŸ“ e
    β”‚    └── πŸ“ evaluationcontext.colour // (1)!
    β”‚         β”œβ”€β”€ πŸ“ 0.1.0
    β”‚         └── πŸ“ 0.1.1
    β”‚              β”œβ”€β”€ πŸ“ lib
    β”‚              β”‚    └── functions.tmdl // (2)!
    β”‚              β”œβ”€β”€ πŸ“„ icon.png // (3)!
    β”‚              β”œβ”€β”€ πŸ“„ README.md // (4)!
    β”‚              └── πŸ“„ manifest.daxlib // (5)!
    β”œβ”€β”€ πŸ“ ...
    └── πŸ“ z
  1. Your library
  2. Required - Your DAX UDF functions
  3. Optional - Icon for your library
  4. Optional - Docs for your library
  5. Required - Declares package properties

Required: Contains TMDL definition of the functions within your library

Naming Convention

There are some guidelines on DAX UDF naming conventions

Annotation

TDML script must not have CreateOrReplace keyword

Functions must have the following annotations:

annotation DAXLIB_PackageId = EvaluationContext.Colour
annotation DAXLIB_PackageVersion = 0.1.2-beta
/// Int to Hex conversion
/// number  INT64   The integer to convert
/// padTo   INT64   Optional: Minimum number of characters in result
function 'EvaluationContext.Colour.Int.ToHex' =
    (
      number: INT64,
      padTo: INT64
    ) =>

      VAR MinPadding = IF( number = 0, 1, CEILING( LOG( number + 1, 16 ), 1 ) )
      VAR ActualPadding = MAX( MinPadding, IF( ISBLANK( padTo ), MinPadding, padTo ) )
      VAR BitTable = GENERATESERIES( 1, ActualPadding )
      VAR Hex =
        CONCATENATEX(
          BitTable,
          VAR c = MOD( TRUNC( number / POWER( 16, [Value] - 1 ) ), 16 )
          RETURN
            SWITCH( c, 10, "A", 11, "B", 12, "C", 13, "D", 14, "E", 15, "F", c ),
          "",
          [Value],
          DESC
        )

      RETURN Hex

  annotation DAXLIB_PackageId = EvaluationContext.Colour
  annotation DAXLIB_PackageVersion = 0.1.2-beta
...

Required: The package properties in JSON format

{
  "$schema": "https://raw.githubusercontent.com/sql-bi/daxlib/refs/heads/main/schemas/manifest/1.0.0/manifest.1.0.0.schema.json",
  "id": "EvaluationContext.Colour",
  "version": "0.1.2-beta",
  "authors": "Jake Duddy",
  "description": "A comprehensive set of User-Defined Functions designed to enable easy manipulation of hex colours",
  "tags": "DAX,UDF,colour",
  "releaseNotes": "Added Documentation page and `EvaluationContext.Colour.Hex.Interpolate` function",
  "projectUrl": "https://evaluationcontext.github.io/EvaluationContext.Colour/",
  "repositoryUrl": "https://github.com/sql-bi/daxlib/tree/main/packages/e/evaluationcontext.colour",
  "icon": "/icon.png", // (1)!
  "readme": "/README.md" // (2)!
}
  1. Required if you include a icon.png file
  2. Required if you include a README.md file

Optional: icon for library

Remarks

The icon file must be in PNG format (.PNG), with a maximum size of 100 KB

Optional: Markdown docs file, with general information about the library, usage instructions, examples, and any notes for users

Remarks

The file must be in Markdown format (.MD), with a maximum size of 100 KB

For security reasons, only a limited set of Markdown features are supported, and external links may be restricted to trusted domains

  • When you are ready to publish a version of the library, submit a pull request from your fork to daxlib/daxlib
  • After approval your library will appear on DAX Lib for other to download and use

Packages are immutable

After a pull request has been accepted, Packages are immutable. If you want to submit any changes to functions or files, a new version (i.e. v0.1.0 v0.2.0 ) must be created, and function annotations and manifest.daxlib must be updated with the new version number. Changes can then be submitted with a new pull request.

Medium/large LibraryΒΆ

The process for Medium/Large libraries uses a extended workflow.

We still need a fork of daxlib/daxlib (i.e. evaluationscontext/daxlib), and will still submit a pull request to daxlib/daxlib to publish a library.

The difference is that development of the library will occur on a fork of daxlib/lib-quickstart-template (one per library i.e. evaluationcontext/evaluationcontext.colour). A github workflow can be run on evaluationcontext/evaluationcontext.colour, which will push the library to a new, version specific, branch of evaluationcontext/daxlib, which can then be submitted via a pull request to daxlib/daxlib.

sequenceDiagram
    participant DaxLib as daxlib.org
    participant Main as daxlib/daxlib
    participant Fork as evaluationcontext/daxlib
    participant LibRepo1 as evaluationcontext/evaluationcontext.colour

    Main->>Fork: 1. Fork repository
    LibRepo1->>LibRepo1: 2. Develop library
    LibRepo1->>Fork: 3. Workflow creates branch
    Fork->>Main: 4. Submit pull request
    Main->>Main: 5. Review & merge
    Main->>DaxLib: 6. Package deployed

Why Create a Medium/large Library?ΒΆ

Since you have a specific repo dedicated to your library you are able to:

  • Connect with your users with GitHub issues
  • Collaborate with others to develop the library
  • Add documentation site and host (for example) on GitHub Pages
  • Opens the door for auto-documentation generation

Creating a Medium/large LibraryΒΆ

Creating a Library RepoΒΆ

Let's start by creating a development repo ( evaluationcontext/evaluationcontext.colour) from daxlib/lib-quickstart-template. This is where we can develop our library.

Use This Template

CreateRepo

Modifying RepoΒΆ

Now we have a development repo we need to update it's content.

  • Go to vscode and run git clone https://github.com/EvaluationContext/evaluationcontext.colour.git

daxlib/lib-quickstart-template structure

We can see the structure is slightly different, but the required content remain the same, except your library now lives in the src folder

β”œβ”€β”€ πŸ“ .github
β”‚    └── πŸ“ workflows
β”‚        └── πŸ“„ publish-package.yml // (1)!
└── πŸ“ src // (2)!
     β”œβ”€β”€ πŸ“ lib
     β”‚    └── functions.tmdl // (3)!
     β”œβ”€β”€ πŸ“„ icon.png // (4)!
     β”œβ”€β”€ πŸ“„ README.md // (5)!
     └── πŸ“„ manifest.daxlib // (6)!
  1. Workflow to create a pull request to daxlib/daxlib repo
  2. Your library
  3. Required - Your DAX UDF functions
  4. Optional - Icon for your library
  5. Optional - Docs for your library
  6. Required - Declares package properties
  • Since I already have a Small Library I can copy the files to src folder
  • Since this will be a new version I need to update the version number in manifest.daxlib (0.1.2-beta 0.1.3-beta)
  • I can also update the main repo README.md to give specific info about this library

Annotation Placeholders

We are able to replace the annotation values in functions.tmdl with placeholders. These will be overwritten by the version specified in manifest.daxlib when running the publish-package.yml workflow.

- annotation DAXLIB_PackageId = EvaluationContext.Colour
+ annotation DAXLIB_PackageId = __PLACEHOLDER_PACKAGE_ID__

- annotation DAXLIB_PackageVersion = 0.1.3-beta
+ annotation DAXLIB_PackageVersion = __PLACEHOLDER_PACKAGE_VERSION__

Adding a Docs SiteΒΆ

For my version of the library docs I used Jekyll and the Just the Docs theme, primarily because I have been using the chirpy Material for my blog. But I have recently transitioned my blog over to the Material Theme for MKDocs, as it has some really nice functionality, and faster build times. So lets quickly add a Material for MKDocs site definition to the repo.

Material for MKDocs

The Material for MKDocs docs site give really good documentation for how to create a site and clear explanation of all the features and how to use them. Additionally this video series is very good at getting you started.

I am going to some files to define the site to the repo:

β”œβ”€β”€ πŸ“ .devcontainer // (1)!
β”‚    β”œβ”€β”€ πŸ“„ devcontainer.json
β”‚    └── πŸ“„ Dockerfile
β”œβ”€β”€ πŸ“ .github
β”‚    └── πŸ“ workflows
β”‚        β”œβ”€β”€ πŸ“„ publish-package.yml
β”‚        └── πŸ“„ ci.yml // (3)!
β”œβ”€β”€ πŸ“ src
β”‚    β”œβ”€β”€ πŸ“ lib
β”‚    β”‚    └── functions.tmdl
β”‚    β”œβ”€β”€ πŸ“„ icon.png
β”‚    β”œβ”€β”€ πŸ“„ README.md
β”‚    └── πŸ“„ manifest.daxlib
β”œβ”€β”€ πŸ“ docs // (4)!
β”‚    β”œβ”€β”€ πŸ“„ index.md
β”‚    └── πŸ“„ ...
β”œβ”€β”€ πŸ“ PowerBI // (5)!
β”‚    β”œβ”€β”€ πŸ“„ Model.pbip
β”‚    └── πŸ“„ ...
β”œβ”€β”€ πŸ“„ mkdocs.yml // (7)!
β”œβ”€β”€ πŸ“„ requirements.txt // (2)!
└── πŸ“„ .gitignore // (6)!
  1. Dev Container configuration for containerized development
  2. Python dependencies for MKDocs and Material theme
  3. GitHub workflow to build and deploy site to gh-pages branch
  4. Markdown files for all site pages
  5. Power BI Project file for function testing and examples
  6. Ignore PBIP and MKDocs specific files
  7. Site configuration

Once I have everything setup I can run the run the site in the Dev Container.

Dev Container dependencies

To run dev containers you need Docker Desktop installed. Additionally if you are running on Windows you will need to install Windows Subsystem for Linux (WSL).

Since MKdocs runs on python, you could could install python, and pip install the dependencies, on your machine without a container.

Once the container is built I can go to the terminal and serve the site on localhost.

mkdocs serve --livereload

Then view the site at http://localhost:8000/ and test to make sure the site is functioning correctly.

MKdocs Serve

Then we can push to GitHub, this will run the ci job, which will execute mkdocs build, generating the html pages, and saving the result to a gh-pages branch.

We can now setup GitHub pages to use the gh-pages branch as a source to deploy our site, by selecting Setting from the top nav bar of the Git Hub repo, select pages and set Deploy from a branch and set the branch to gh-pages, and select save.

GitHub Pages Setup

We will see a pages build and deployment action kick off, which will deploy the site.

Site Build

Then we can navigate to our site URL and confirm it deployed successfully.

Deployed Site

Deploying LibraryΒΆ

After that brief detour, we can deploy the library by following the Publish Your Library guidance.

We first need to create a Personal Access Token, granting read/write permissions on evaluationcontext/daxlib.

Generate PAT Token

We add the token as a secret on evaluationcontext/evaluationcontext.colour, granting these permission to evaluationcontext/daxlib. So that the workflow run from evaluationcontext/evaluationcontext.colour can create a new branch in evaluationcontext/daxlib

Add Secret

Navigate to actions, select publish-package and Run workflow.

publish-package

Once this has run we can navigate to our evaluationcontext/daxlib, and we confirm new branch ( evaluationcontext.colour/publish-EvaluationContext.Colour-0.1.3-beta) has been created.

ForkNewBranch

If we go back the actions section of evaluationcontext/evaluationcontext.colour and open the completed publish-package job, you can see we get the option to open a pull request.

Completed publish-package job

Then we can select Open Pull Request and Create pull request to create a pull request to daxlib/daxlib.

Open Pull Request

The pull request will then be reviewed by the DAX Lib maintainers. If changes are requested during the review:

  • Apply the requested fixes to your code in the development repo, and commit them to your repository
  • Re-run the publish-package workflow
  • The pull request will be automatically updated

Once your pull request is approved and merged, your library will be automatically published on daxlib.org.

Comments