How the loyalsoldier/geoip Repository Generates GeoIP Format Files Weekly: Internal Process and Dependencies
The loyalsoldier/geoip repository automates GeoIP file generation every Thursday at 00:00 UTC through a GitHub Actions workflow that downloads MaxMind GeoLite2 data, compiles a Go 1.25 binary, and executes a plugin-based conversion pipeline to produce multiple output formats including V2Ray DAT and MaxMind MMDB.
The loyalsoldier/geoip project maintains an open-source pipeline for building customizable GeoIP databases used by proxy tools like V2Ray, Clash, and sing-box. Understanding the internal process for generating GeoIP format files weekly reveals how the repository transforms raw MaxMind CSV data into optimized distribution files without manual intervention.
Weekly Automation Workflow
The entire generation process is orchestrated by .github/workflows/build.yml, which triggers automatically via cron: "0 0 * * 4"—midnight UTC every Thursday.
Pipeline Stages
The workflow executes eleven distinct stages to ensure deterministic, reproducible builds:
-
Repository Checkout — Uses
actions/checkout@v6to pull the full git history required for release management. -
Go Environment Setup — Installs Go 1.25 (as declared in
go.mod) usingactions/setup-go@v6. -
Timestamp Generation — Creates a timestamp variable used for release tags and asset versioning.
-
MaxMind Data Acquisition — Downloads the latest GeoLite2-Country and GeoLite2-ASN archives using the secret
MAXMIND_GEOLITE2_LICENSEvia authenticatedcurlrequests. -
File Preparation — Unpacks tar.gz and zip archives, copying
.mmdbfiles and CSV datasets into./output/and./geolite2/directories using standard Bash utilities. -
Binary Compilation and Conversion — Executes
go build ./to compile the CLI, then runs./geoip convert -c ./config.jsonto process all configured inputs and outputs. -
MMDB Integrity Verification — Installs
github.com/maxmind/mmdbverifyand validates each generated.mmdbfile against MaxMind specifications. -
Checksum Generation — Computes SHA-256 hashes for all
.datand.mmdbfiles, writing them to*.sha256sumfiles. -
Release Branch Deployment — Commits generated assets to a lightweight
releasebranch used exclusively for GitHub Release attachments. -
CDN Cache Purging — Sends HTTP PURGE requests to jsDelivr for every new asset, ensuring global mirrors refresh immediately.
-
Artifact Publication — Uses
svenstaro/upload-release-action@v2to publish final assets as a timestamped GitHub Release, removing intermediate CSV files and raw archives beforehand to keep the distribution clean.
Core Conversion Architecture
The conversion logic centers on a command-line interface defined in main.go and convert.go, implementing a modular plugin system that decouples data ingestion from format output.
CLI Entry Points
In main.go, the application registers the convert sub-command. The convert.go file implements this command, parsing the -c or --config flag to load config.json and orchestrating the transformation pipeline.
Plugin-Based Data Flow
The architecture implements two primary interfaces:
-
Input Plugins — Types like
maxmindGeoLite2CountryCSV(inplugin/maxmind/maxmind_country_csv_in.go),text(plugin/plaintext/text_in.go),json(plugin/special/json_in.go), andprivate(plugin/special/private.go) implement theInputConverterinterface. Each plugin callscontainer.Addorcontainer.Removemethods to populate a central data structure defined inlib/container.goandlib/entry.go. -
Output Plugins — Types like
v2rayGeoIPDat(plugin/v2ray/dat_out.go),maxmindMMDB(plugin/maxmind/maxmind_country_mmdb_out.go),singboxSRS, andclashRuleSetimplement theOutputConverterinterface, serializing the container contents into target formats using format-specific writers.
The container maintains CIDR lists and supports add/remove operations, enabling complex transformations like merging MaxMind data with custom IP lists while excluding specific ranges.
Critical Go Dependencies
All third-party modules are declared in go.mod. The generation pipeline relies on specialized libraries for compression, IP handling, and MaxMind compatibility:
-
github.com/klauspost/compress— Handles ZIP/ZIP-64 operations for archive extraction and V2Ray DAT output compression. -
github.com/maxmind/mmdbwriter— Writes MaxMind MMDB files via themaxmindMMDBoutput plugin, including themmdbtypesubpackage for data types. -
github.com/oschwald/geoip2-golang/v2— Reads original MaxMind.mmdbfiles when the pipeline requires additional metadata from source databases. -
github.com/spf13/cobra— Provides the CLI framework powering thegeoip convertcommand structure. -
github.com/tailscale/hujson— Parses JSON configuration files while preserving comments, used bylib/config.gofor human-readable configuration. -
github.com/tidwall/gjson— Enables fast extraction of IP ranges from remote JSON sources like Google and Fastly endpoint lists. -
go4.org/netipx— Supplies advanced IP address utilities for CIDR merging and prefix manipulation. -
google.golang.org/protobuf— Serializes V2RayGeoIPprotobuf messages indat_out.go. -
gopkg.in/yaml.v2— Parses YAML fragments embedded in certain plugin configurations.
Configuration-Driven Generation
The config.json file acts as the declarative blueprint, separating data sources from output targets without requiring code changes.
Input Configuration
The input array defines data sources using type, action (add/remove), and args fields:
-
MaxMind CSV —
maxmindGeoLite2CountryCSVtype readsGeoLite2-Country-Locations-en.csv,GeoLite2-Country-Blocks-IPv4.csv, andGeoLite2-Country-Blocks-IPv6.csv. -
Remote Text Lists —
texttype fetches plain-text IP lists from URIs likehttps://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt. -
JSON Endpoints —
jsontype extracts CIDR ranges from remote JSON APIs usinggjsonselectors. -
Private Ranges —
privatetype injects standard private IP ranges (RFC 1918) into the container.
Output Configuration
The output array specifies destination formats using the same type/action/args pattern:
-
V2Ray DAT —
v2rayGeoIPDattype generatesgeoip.datprotobuf files compatible with V2Ray and Xray cores. -
MaxMind MMDB —
maxmindMMDBtype producesCountry.mmdbfiles, supportingsourceMMDBURIfor template inheritance andoverwriteListfor selective updates. -
Proxy Tool Formats — Additional types generate Clash Rule Sets, Surge rule files, and sing-box SRS databases.
Running the Pipeline Locally
Developers can replicate the weekly generation process on local machines for testing or custom builds.
Building and Executing
# Compile the binary
go build -o geoip .
# Run conversion with default configuration
./geoip convert -c ./config.json
Adding Custom Data Sources
To include a new IP list in the next generation cycle, add an entry to the input array in config.json:
{
"type": "text",
"action": "add",
"args": {
"name": "custom",
"uri": "https://example.com/custom-ip-list.txt",
"onlyIPType": "ipv4"
}
}
Defining Additional Outputs
To generate a specialized V2Ray database containing only specific categories, extend the output array:
{
"type": "v2rayGeoIPDat",
"action": "output",
"args": {
"outputDir": "./output",
"outputName": "geoip-custom.dat",
"wantedList": ["cn", "tor", "custom"]
}
}
Summary
- The loyalsoldier/geoip repository triggers automated builds every Thursday via
cron: "0 0 * * 4"in.github/workflows/build.yml. - A Go 1.25 binary processes data through a plugin architecture implementing
InputConverterandOutputConverterinterfaces. - The pipeline downloads fresh MaxMind GeoLite2-Country and GeoLite2-ASN data using authenticated API requests.
- Core data structures in
lib/container.gomanage CIDR additions and removals across all input sources. - Output formats include V2Ray DAT, MaxMind MMDB, Clash rules, and sing-box SRS via specialized dependencies like
mmdbwriterandprotobuf. - The entire workflow is configurable through
config.json, requiring no code changes to modify inputs or outputs.
Frequently Asked Questions
How does the repository schedule its weekly GeoIP generation?
The repository uses a GitHub Actions workflow defined in .github/workflows/build.yml that triggers automatically via the cron expression 0 0 * * 4, which executes at 00:00 UTC every Thursday without requiring manual intervention.
What validates the integrity of generated MaxMind MMDB files?
After conversion, the workflow installs the github.com/maxmind/mmdbverify tool and validates each generated .mmdb file against MaxMind's official specification before including it in the GitHub Release, ensuring database compatibility with standard readers.
Which Go version and dependencies power the conversion engine?
The pipeline requires Go 1.25 as specified in go.mod, with critical dependencies including github.com/maxmind/mmdbwriter for MMDB creation, github.com/klauspost/compress for archive handling, and google.golang.org/protobuf for V2Ray DAT serialization.
How can I customize the weekly output formats without modifying Go code?
Edit the config.json file at the repository root to add new entries to the input array (for data sources) or output array (for target formats), then commit the changes; the next scheduled run will automatically pick up the new configuration and generate the additional files.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →