Skip to main content
Custom source method allows you to build sources for SRPM using your own user-defined script. This provides maximum flexibility when generating build sources.

Overview

The custom source method executes a script that generates a spec file and optionally any other files needed to build a source RPM (tarballs, patches, etc.). The script runs in a mock chroot under a non-privileged user (mockbuild) with internet access.
The script cannot be an SRPM itself. If your tool generates an SRPM, you must extract it within the script.

Required Configuration

Only two parameters are required:

Script

The script file content, written in any scripting language. Important:
  • Specify the shebang properly (e.g., #!/bin/sh for shell scripts)
  • The interpreter must be available in the chroot (may need to request via builddeps)
  • Output files go to the current working directory by default

Chroot

The mock chroot where the script executes. Default is fedora-latest-x86_64 (the latest stable or branched Fedora available at build time).

Optional Parameters

Space-separated list of packages pre-installed into the build chroot before script execution.
--script-builddeps "git python3-setuptools rpmdevtools"
Directory where the script generates output. Defaults to current working directory.
--script-resultdir results

Environment Variables

Copr defines these environment variables for your script:
VariableDescriptionExample
COPR_OWNEROwner of the project (user or group)@copr or username
COPR_PROJECTName of the projectmy-project
COPR_PACKAGEName of the package being builtmy-package
COPR_RESULTDIROutput directory (see resultdir parameter)/builddir/results

Script Requirements

The script executes under a non-privileged user (mockbuild). You cannot install RPM packages from within the script - declare them in builddeps instead.
Your script must generate:
  1. Spec file (required)
  2. Source archives referenced by Source statements (typically tarballs)
  3. Patches referenced by Patch statements (optional)
All files should be placed in the resultdir directory.

Extracting Existing SRPMs

If your tool generates an SRPM, extract it within the script:
#!/bin/sh -xe
git clone example.com/foo.git && cd foo
make srpm
bsdtar xf *.src.rpm -C "$COPR_RESULTDIR"

Examples

Simple Spec File Download

#!/bin/sh -x
curl https://praiskup.fedorapeople.org/quick-package.spec -O

Using SRPM Source

#!/bin/sh -x
make dist-srpm
rpmdev-extract redhat/rpm/SRPMS/quick-package-*.src.rpm
mv quick-package*src/* ./

Python Package with Git Submodules

A more complex example showing git cloning, tarball generation, and dynamic versioning:
#!/bin/sh

mkdir -p results
resultdir=$(readlink -f results)

set -x # verbose output
set -e # fail on any error

# Obtain the source code
git clone https://github.com/praiskup/resalloc --recursive --depth 1
cd resalloc

# 1. Generate source tarball into resultdir
python setup.py sdist -d "$resultdir"

# 2. Copy spec file and modify release number
cd rpm
release='~'$(date +"%Y%m%d_%H%M%S")
sed "s/\(^Release:[[:space:]]*[[:digit:]\+]\)/\1$release/" resalloc.spec \
    > "$resultdir"/resalloc.spec

# 3. Copy other sources
cp *.service "$resultdir"

Webhook Support

Custom source method supports custom webhooks. Unlike other methods, the custom method doesn’t parse webhook payloads automatically - that’s your responsibility.

Hook Payload

When a webhook triggers a build, the payload is dumped to $PWD/hook_payload file. Your script must:
  1. Read and parse the hook_payload file
  2. Determine what to build based on the payload
  3. Generate appropriate sources
It’s valid to trigger custom webhooks without any payload:
curl -X POST <THE_CUSTOM_HOOK_URL>

Best Practices

  1. Use set -e to fail fast on errors
  2. Use set -x for verbose output to aid debugging
  3. Specify absolute paths or use $COPR_RESULTDIR for output
  4. Test locally in a mock chroot before deploying
  5. Keep scripts portable - avoid root-requiring operations
  6. Declare all dependencies in builddeps parameter

Limitations

  • No root access: Scripts run as mockbuild user
  • No package installation: Use builddeps to declare required packages
  • Internet required: Most scripts need network access for cloning/downloading
  • Build timeout: Scripts must complete within project timeout limits

Advanced Use Cases

For more complex CI/CD workflows with custom source methods, see this blog post about CI/CD with Copr.

Build docs developers (and LLMs) love