Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
66a012f
Add GitHub Actions workflow for publishing feature
wdconinc Aug 24, 2025
51fda3e
feat: Add devcontainer feature and refactor for modularity
wdconinc Aug 24, 2025
bdbd47b
Re-add Docker usage instructions to README
wdconinc Aug 24, 2025
51241d3
Bring back some filename consistency and configuration
wdconinc Aug 24, 2025
34c19b0
Fix link to devcontainer features
wdconinc Aug 24, 2025
473d9ac
Ensure setup scripts run in bash
wdconinc Aug 24, 2025
3080031
Fix typo
wdconinc Aug 24, 2025
788f05f
Add feature package test workflow
wdconinc Aug 24, 2025
93cff7d
Use sudo -E to preserve environment (configuration)
wdconinc Aug 24, 2025
86135f4
Rename workflow to Package Devcontainer Feature
wdconinc Aug 24, 2025
5de76b7
Configure CVMFS before mounting on macOS
wdconinc Aug 24, 2025
df83e80
Re-add on need for sleep on macOS
wdconinc Aug 24, 2025
195f0bb
Use correct src/ directory in devcontainer features generate-docs
wdconinc Aug 24, 2025
ca26869
Re-add CVMFS config package logic
wdconinc Aug 25, 2025
f61ea44
Fix condition for installing CVMFS config package in install-cvmfs-li…
wdconinc Aug 25, 2025
6ef1714
Update create-config.sh to remove sudo usage
wdconinc Aug 25, 2025
86259e9
Move GitHub Copilot instruction and devcontainer feature documentation
wdconinc Aug 25, 2025
4ab8ca6
Also mount requested repos in linux
wdconinc Aug 25, 2025
1398c01
Move devcontainer feature to top level
wdconinc Aug 25, 2025
7cbd63a
Enhance publish workflow to include version input and update devconta…
wdconinc Aug 25, 2025
8751251
Add devcontainer configuration for CVMFS Action Test
wdconinc Aug 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .devcontainer/devcontainer-with-cvmfs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "CVMFS Action Test",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/cvmfs-contrib/github-action-cvmfs/cvmfs": {}
},
"forwardPorts": []
}
File renamed without changes.
14 changes: 14 additions & 0 deletions .github/workflows/package-feature.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Package Devcontainer Feature
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- name: Install Devcontainer CLI
run: npm install -g @devcontainers/cli
- name: Package CVMFS Feature
run: devcontainer features package src/cvmfs/
- name: Generate CVMFS Feature Docs
run: devcontainer features generate-docs -p src/ -n cvmfs-contrib/cvmfs
40 changes: 40 additions & 0 deletions .github/workflows/publish-feature.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Publish Devcontainer Feature

on:
workflow_call:
inputs:
version:
description: 'The version to publish'
required: true
type: string
release:
types: [created]

jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Install Devcontainer CLI
run: npm install -g @devcontainers/cli

- name: Login to GitHub Container Registry
run: echo "${{ secrets.WRITE_PACKAGES_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin

- name: Add version to environment
run: |
VERSION="${{ inputs.version || github.ref_name }}"
echo "VERSION=$VERSION" >> $GITHUB_ENV

- name: Add version to devcontainer-feature.json
run: |
jq --arg VERSION "${{ env.VERSION }}" '.version = $VERSION' src/cvmfs/devcontainer-feature.json > tmp.json
mv tmp.json src/cvmfs/devcontainer-feature.json

- name: Publish Devcontainer Feature
run: devcontainer features publish --namespace ${{ github.actor }}/${{ github.repository }} .

- name: Build Devcontainer Feature
run: devcontainer build --workspace-folder . --image-name test-cvmfs-feature --additional-features ghcr.io/${{ github.actor }}/${{ github.repository }}/cvmfs:${{ env.VERSION }}
39 changes: 39 additions & 0 deletions README.devcontainer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# CVMFS Devcontainer Feature

This directory contains a devcontainer feature for installing and configuring the CVMFS client.

## Publishing to GHCR

This feature is intended to be published to the GitHub Container Registry (GHCR) to be easily reusable by other projects.

### Manual Publishing

1. **Install the Devcontainer CLI:**
```bash
npm install -g @devcontainers/cli
```

2. **Create a Personal Access Token (PAT):**
* Go to GitHub **Settings** > **Developer settings** > **Personal access tokens** > **Tokens (classic)**.
* Generate a new token with the `write:packages` scope.
* Export the token as an environment variable:
```bash
export WRITE_PACKAGES_TOKEN=your-personal-access-token
```

3. **Log in to GHCR:**
```bash
echo $WRITE_PACKAGES_TOKEN | docker login ghcr.io -u your-github-username --password-stdin
```

4. **Publish the Feature:**
Run the following command from the root of this repository. The namespace should match the GitHub organization (`cvmfs-contrib`).
```bash
devcontainer features publish src/cvmfs --namespace cvmfs-contrib/
```

### Automated Publishing

This repository is configured with a GitHub Actions workflow to automate this process. When a new release is published on GitHub, the workflow will automatically build and publish the feature to GHCR.

For this to work, the `WRITE_PACKAGES_TOKEN` secret (a Personal Access Token with `write:packages` scope) must be configured in the repository's **Settings > Secrets and variables > Actions**.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,27 @@ jobs:

This GitHub Action installs the [CernVM-FS package](https://cernvm.cern.ch/fs/#download), and configures it with the `CVMFS_CLIENT_PROFILE='single'` and `CVMFS_USE_CDN='yes'` to avoid any overhead on the CernVM-FS stratum 1 servers that you are accessing, this GitHub Action uses the [OpenHTC](https://openhtc.io) caching edge servers.

## Devcontainer Usage

This repository includes a pre-configured devcontainer for a consistent development environment. It uses the CVMFS devcontainer feature located in the `src/cvmfs` directory.

To use it, open this repository in a devcontainer-compatible editor like VS Code with the Dev Containers extension.

You can add other functionalities to your devcontainer by including more features. A comprehensive list of contributed features can be found in the [devcontainer feature index](https://containers.dev/features).

For example, you can add the following to your `devcontainer.json` to use this feature:
```json
{
"name": "CVMFS Action Dev",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/cvmfs-contrib/features/cvmfs:1": {
"CVMFS_REPOSITORIES": "alice.cern.ch,atlas.cern.ch"
}
}
}
```

## Limitations

This GitHub Action is only expected to work in workflows that [run on](https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on) ubuntu. There is experimental support for `macOS` (11+).
Expand Down
9 changes: 8 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,14 @@ runs:
path: |
${{ inputs.apt_cache }}
- run: |
${{ github.action_path }}/setup-cvmfs.sh
if [ "$RUNNER_OS" == "Linux" ]; then
bash ${{ github.action_path }}/setup-cvmfs-linux.sh
elif [ "$RUNNER_OS" == "macOS" ]; then
bash ${{ github.action_path }}/setup-cvmfs-macos.sh
else
echo "Unsupported platform: $RUNNER_OS"
exit 1
fi
shell: bash
env:
ACTION_PATH: ${{ github.action_path }}
Expand Down
6 changes: 3 additions & 3 deletions createConfig.sh → create-config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ declare -a vars=(CVMFS_ALIEN_CACHE
CVMFS_WORKSPACE
)

sudo mkdir -p /etc/cvmfs
echo "# cvmfs default.local file installed with cvmfs-contrib/github-action-cvmfs" | sudo tee /etc/cvmfs/default.local
mkdir -p /etc/cvmfs
echo "# cvmfs default.local file installed with cvmfs-contrib/github-action-cvmfs" | tee /etc/cvmfs/default.local
for var_name in "${vars[@]}"
do
if [ ! -z "$(eval "echo \$$var_name")" ]; then
echo "$var_name='$(eval "echo \$$var_name")'" | sudo tee -a /etc/cvmfs/default.local
echo "$var_name='$(eval "echo \$$var_name")'" | tee -a /etc/cvmfs/default.local
fi
done
24 changes: 24 additions & 0 deletions devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "CVMFS",
"id": "cvmfs",
"version": "1.4.3",
"description": "Installs CVMFS client",
"options": {
"CVMFS_REPOSITORIES": {
"type": "string",
"default": "sft.cern.ch",
"description": "Comma-separated list of fully qualified repository names that shall be mountable under /cvmfs"
},
"CVMFS_CONFIG_PACKAGE": {
"type": "string",
"default": "cvmfs-config-default",
"description": "URL to the cvmfs config package to install"
},
"CVMFS_HTTP_PROXY": {
"type": "string",
"default": "DIRECT",
"description": "Chain of HTTP proxy groups used by CernVM-FS. Defaults to DIRECT)"
}
},
"entrypoint": "install-cvmfs-linux.sh"
}
42 changes: 42 additions & 0 deletions install-cvmfs-linux.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env bash
# Shared CVMFS install and config logic for Linux
set -e

# Install CVMFS release package
CVMFS_UBUNTU_DEB_LOCATION=${CVMFS_UBUNTU_DEB_LOCATION:-https://ecsft.cern.ch/dist/cvmfs/cvmfs-release/cvmfs-release-latest_all.deb}
APT_ARCHIVES=/var/cache/apt/archives/
mkdir -p ${APT_ARCHIVES}
if [ ! -f ${APT_ARCHIVES}/cvmfs-release-latest_all.deb ] ; then
curl -L -o ${APT_ARCHIVES}/cvmfs-release-latest_all.deb ${CVMFS_UBUNTU_DEB_LOCATION}
fi
dpkg -i ${APT_ARCHIVES}/cvmfs-release-latest_all.deb

# Install CVMFS and config package
apt-get -q update
if [ "${CVMFS_CONFIG_PACKAGE}" == "cvmfs-config-default" ]; then
apt-get -q -y install cvmfs cvmfs-config-default
else
curl -L -o ${APT_ARCHIVES}/cvmfs-config.deb ${CVMFS_CONFIG_PACKAGE}
dpkg -i ${APT_ARCHIVES}/cvmfs-config.deb
fi

# Write config from environment variables
mkdir -p /etc/cvmfs

echo "# cvmfs default.local file installed by cvmfs-install-core.sh" > /etc/cvmfs/default.local
for var_name in $(compgen -A variable | grep ^CVMFS_)
do
if [ -n "$(eval echo \$$var_name)" ]; then
echo "$var_name='$(eval echo \$$var_name)'" >> /etc/cvmfs/default.local
fi
done

# Configure CVMFS
bash create-config.sh
bash setup-cvmfs-config.sh

# Mount repositories
for repo in $(echo ${CVMFS_REPOSITORIES} | sed "s/,/ /g")
do
sudo mount -t cvmfs ${repo} /cvmfs/${repo}
done
13 changes: 13 additions & 0 deletions setup-cvmfs-config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
# CVMFS configuration logic
set -e

echo "::group::Running cvmfs_config setup"
sudo cvmfs_config setup
retConfig=$?
if [ $retConfig -ne 0 ]; then
echo "!!! github-action-cvmfs FAILED !!!"
echo "cvmfs_config setup exited with ${retConfig}"
exit $retConfig
fi
echo "::endgroup::"
22 changes: 22 additions & 0 deletions setup-cvmfs-linux.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
# Linux-specific wrapper for CI/CD or local install
set -e

# Optional: handle APT cache for CI/CD
if [ -n "${APT_CACHE}" ]; then
echo "Using cache from ${APT_CACHE}"
mkdir -p ${APT_CACHE}/archives/ ${APT_CACHE}/lists/
sudo cp -r ${APT_CACHE}/archives /var/cache/apt
sudo cp -r ${APT_CACHE}/lists /var/lib/apt
fi

# Call shared install logic (preserve environment with configuration)
sudo -E bash "$(dirname "$0")/install-cvmfs-linux.sh"

# Optional: update cache after install
if [ -n "${APT_CACHE}" ]; then
echo "Updating cache to ${APT_CACHE}"
mkdir -p ${APT_CACHE}/archives/ ${APT_CACHE}/lists/
cp /var/cache/apt/archives/*.deb ${APT_CACHE}/archives/
cp /var/lib/apt/lists/*_dists_* ${APT_CACHE}/lists/
fi
29 changes: 29 additions & 0 deletions setup-cvmfs-macos.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env bash
# macOS-specific CVMFS install logic
set -e

echo "warning: MacOS support is experimental."

brew tap macos-fuse-t/cask
brew tap cvmfs/homebrew-cvmfs
brew install cvmfs

# Create /cvmfs mountpoint using synthetic firmlink
sudo zsh -c 'echo -e "cvmfs\tUsers/Shared/cvmfs\n#comment\n" > /etc/synthetic.conf'
sudo chown root:wheel /etc/synthetic.conf
sudo chmod a+r /etc/synthetic.conf
sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t || true

# Configure CVMFS
bash create-config.sh
bash setup-cvmfs-config.sh

# Mount repositories
for repo in $(echo ${CVMFS_REPOSITORIES} | sed "s/,/ /g")
do
mkdir -p /Users/Shared/cvmfs/${repo}
sudo mount -t cvmfs ${repo} /Users/Shared/cvmfs/${repo}
done

# Fuse-t can have a brief lag after mounting before the mountpoint responds
sleep 3
88 changes: 0 additions & 88 deletions setup-cvmfs.sh

This file was deleted.

Loading