Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 15 additions & 0 deletions .forgejo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Forgejo Actions Placeholder

This directory exists to prevent Forgejo from falling back to GitHub Actions workflows.

## Why is this directory empty?

This project uses **Woodpecker CI** (configured in `.woodpecker.yml`), not Forgejo Actions.

When Forgejo detects this directory, it will **not** attempt to use any GitHub Actions workflows that might exist in `.github/workflows/`. Without this directory, Forgejo would try to execute GitHub Actions as a fallback, which is not desired for this project.

## Note

- **DO NOT DELETE** this directory unless you want to enable GitHub Actions fallback behavior
- If you want to use Forgejo Actions in the future, place workflow files in `.forgejo/workflows/`
- Current CI system: Woodpecker CI (see `.woodpecker.yml`)
84 changes: 84 additions & 0 deletions .github/workflows/woodpecker-plugin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
name: Woodpecker Plugin - Build and Publish

on:
push:
branches: [main, feat/woodpecker-ci-plugin]
paths:
- 'woodpecker-plugin/**'
- 'common/**'
- '.github/workflows/woodpecker-plugin.yml'
pull_request:
paths:
- 'woodpecker-plugin/**'
- 'common/**'
- '.github/workflows/woodpecker-plugin.yml'
workflow_dispatch:

permissions:
contents: read
packages: write

jobs:
build-and-push:
name: Build and push Woodpecker plugin image
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels)
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository_owner }}/devcontainer-build-run-woodpecker
tags: |
# Tag as 'latest' for pushes to main
type=raw,value=latest,enable={{is_default_branch}}
# Tag as 'pr-NUMBER' for pull requests
type=ref,event=pr,prefix=pr-
# Tag as branch name for other branches
type=ref,event=branch
# Tag as sha for commits
type=sha,prefix={{branch}}-

- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
file: ./woodpecker-plugin/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Show image details
run: |
echo "## Woodpecker Plugin Image Published! 🎉" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Image Tags:**" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Usage in Woodpecker CI:**" >> $GITHUB_STEP_SUMMARY
echo '```yaml' >> $GITHUB_STEP_SUMMARY
echo "steps:" >> $GITHUB_STEP_SUMMARY
echo " - name: build-devcontainer" >> $GITHUB_STEP_SUMMARY
echo " image: ghcr.io/${{ github.repository_owner }}/devcontainer-build-run-woodpecker:latest" >> $GITHUB_STEP_SUMMARY
echo " settings:" >> $GITHUB_STEP_SUMMARY
echo " sub_folder: .devcontainer" >> $GITHUB_STEP_SUMMARY
echo " image_name: my-devcontainer" >> $GITHUB_STEP_SUMMARY
echo " image_tag: latest" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
130 changes: 130 additions & 0 deletions .woodpecker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Woodpecker CI configuration for testing the woodpecker-plugin
# This config is only for testing purposes in local Woodpecker CI

when:
event: [push, pull_request, manual]

steps:
# Check code formatting
- name: format-check
image: node:20-alpine
commands:
- cd woodpecker-plugin && npm ci && npm run format-check

# Lint TypeScript code
- name: lint
image: node:20-alpine
commands:
- cd woodpecker-plugin && npm ci && npm run lint

# Install dependencies and build TypeScript
- name: build-typescript
image: node:20-alpine
commands:
- cd common && npm ci && npm run build
- cd ../woodpecker-plugin && npm ci && npm run build
depends_on:
- format-check
- lint

# Run unit tests for env-parser
- name: test-env-parser
image: node:20-alpine
commands:
- cd woodpecker-plugin && npm test
depends_on:
- build-typescript

# Build the plugin Docker image
- name: build-plugin-image
image: docker:latest
commands:
- docker build -f woodpecker-plugin/Dockerfile -t woodpecker-plugin:test .
volumes:
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
- test-env-parser

# Test scenario 1: simple-node (image-based)
- name: test-simple-node-build
image: woodpecker-plugin:test
settings:
sub_folder: woodpecker-plugin-tests/simple-node
image_name: test-simple-node
image_tag: test
volumes:
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
- build-plugin-image

- name: test-simple-node-run
image: test-simple-node:test
commands:
- echo "Testing simple-node DevContainer!"
- node --version
- npm --version
depends_on:
- test-simple-node-build

- name: test-simple-node-run-cmd
image: woodpecker-plugin:test
settings:
sub_folder: woodpecker-plugin-tests/simple-node
run_cmd: echo "run_cmd test!" && node --version
volumes:
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
- test-simple-node-build

# Test scenario 2: with-dockerfile
- name: test-dockerfile-build
image: woodpecker-plugin:test
settings:
sub_folder: woodpecker-plugin-tests/with-dockerfile
image_name: test-dockerfile
image_tag: test
volumes:
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
- build-plugin-image

- name: test-dockerfile-run
image: test-dockerfile:test
commands:
- echo "Testing with-dockerfile DevContainer!"
- node --version
- git --version
depends_on:
- test-dockerfile-build

# Test scenario 3: with-features (features + build args)
- name: test-features-build
image: woodpecker-plugin:test
settings:
sub_folder: woodpecker-plugin-tests/with-features
image_name: test-features
image_tag: test
volumes:
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
- build-plugin-image

- name: test-features-run
image: test-features:test
commands:
- echo "Testing with-features DevContainer!"
- node --version
- git --version
- python3 --version
depends_on:
- test-features-build

- name: test-features-run-cmd
image: woodpecker-plugin:test
settings:
sub_folder: woodpecker-plugin-tests/with-features
run_cmd: echo "Features run_cmd test!" && node --version && git --version && python3 --version
volumes:
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
- test-features-build
47 changes: 47 additions & 0 deletions scripts/build-woodpecker-docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/bin/bash
set -e

script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
repo_root="$script_dir/.."

# Default values
IMAGE_NAME="${IMAGE_NAME:-devcontainer-woodpecker}"
IMAGE_TAG="${IMAGE_TAG:-local}"
PLATFORMS="${PLATFORMS:-linux/amd64}"
PUSH="${PUSH:-false}"

echo "Building Woodpecker Plugin Docker Image"
echo "========================================"
echo "Image: ${IMAGE_NAME}:${IMAGE_TAG}"
echo "Platforms: ${PLATFORMS}"
echo "Push: ${PUSH}"
echo ""

cd "$repo_root"

if [ "$PUSH" = "true" ]; then
echo "Building and pushing multi-platform image..."
docker buildx build \
--platform "$PLATFORMS" \
-f woodpecker-plugin/Dockerfile \
-t "${IMAGE_NAME}:${IMAGE_TAG}" \
--push \
.
else
echo "Building image for local use..."
docker build \
-f woodpecker-plugin/Dockerfile \
-t "${IMAGE_NAME}:${IMAGE_TAG}" \
.
fi

echo ""
echo "==> Docker image built successfully!"
echo " Image: ${IMAGE_NAME}:${IMAGE_TAG}"
echo ""
echo "To test the image locally, run:"
echo " docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \\"
echo " -v \$(pwd):/workspace \\"
echo " -e PLUGIN_RUN_CMD='echo Hello from Dev Container' \\"
echo " -e CI_WORKSPACE=/workspace \\"
echo " ${IMAGE_NAME}:${IMAGE_TAG}"
21 changes: 21 additions & 0 deletions scripts/build-woodpecker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash
set -e

script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"

echo "Building Woodpecker Plugin..."
echo ""

echo "==> Building common"
cd "$script_dir/../common"
npm install
npm run build

echo ""
echo "==> Building woodpecker-plugin"
cd "$script_dir/../woodpecker-plugin"
npm install
npm run build

echo ""
echo "==> Woodpecker plugin build completed successfully!"
24 changes: 24 additions & 0 deletions woodpecker-plugin-tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Woodpecker Plugin Tests

This directory contains integration test scenarios for the woodpecker-plugin.

## Test Scenarios

### `simple-node/`
Basic DevContainer using a pre-built image from Docker Hub.
- Tests: Image-based DevContainer, basic commands

### `with-dockerfile/`
DevContainer with a custom Dockerfile.
- Tests: Dockerfile-based builds, custom package installation

### `with-features/`
DevContainer with features and build arguments.
- Tests: Dockerfile with build args (VARIANT, WELCOME_MESSAGE), DevContainer features (git, python), postCreateCommand

## Running Tests

Tests are executed in the main `.woodpecker.yml` pipeline:
1. Plugin builds the DevContainer image for each scenario
2. Commands are executed inside the built DevContainer
3. Results verify plugin functionality
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "Woodpecker Plugin Test",
"image": "mcr.microsoft.com/devcontainers/javascript-node:20",
"features": {},
"customizations": {
"vscode": {
"extensions": []
}
},
"postCreateCommand": "echo 'DevContainer initialized successfully' && node --version && npm --version"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM node:20-alpine

RUN apk add --no-cache git

USER node
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "Node with Dockerfile",
"dockerFile": "Dockerfile",
"customizations": {
"vscode": {
"extensions": []
}
},
"postCreateCommand": "echo 'DevContainer with Dockerfile initialized!' && node --version && git --version"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
ARG VARIANT=20
FROM node:${VARIANT}-bookworm

ARG WELCOME_MESSAGE="DevContainer with features!"

RUN echo "Building with message: ${WELCOME_MESSAGE}"

USER node
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "Node with Features",
"dockerFile": "Dockerfile",
"build": {
"args": {
"VARIANT": "20",
"WELCOME_MESSAGE": "Hello from Woodpecker CI!"
}
},
"features": {
"ghcr.io/devcontainers/features/git:1": {
"version": "latest"
},
"ghcr.io/devcontainers/features/python:1": {
"version": "3.11"
}
},
"customizations": {
"vscode": {
"extensions": []
}
},
"postCreateCommand": "echo 'Post-create command executed!' && node --version && git --version && python3 --version"
}
Loading