A repo demonstrating the use of git with the 3505 card reader as a pseudo CI/CD tooling option
Go to file
2026-02-06 15:24:22 +00:00
.gitea/workflows reorganized repo and tidied up workflows 2026-02-06 15:13:34 +00:00
jcl testing upload-artefacts step 2026-02-06 13:29:07 +00:00
scripts reorganized repo and tidied up workflows 2026-02-06 15:13:34 +00:00
src testing upload-artefacts step 2026-02-06 13:29:07 +00:00
.gitignore ignore the poetry lock 2026-02-06 12:34:29 +00:00
pyproject.toml update pyproject to include requests 2026-02-06 12:35:47 +00:00
README.MD fancy up the readme 2026-02-06 15:24:22 +00:00

TK5 C90 Projects

A modern development workflow for C90 programming on IBM MVS 3.8j TK5, combining contemporary tooling with mainframe execution.

Overview

This project enables C90 (ANSI C89) development for MVS 3.8j using modern IDEs and Git workflows. Source code is written locally, then automatically uploaded and compiled on the mainframe via CI/CD automation.

How It Works

  1. Local Development: Write C90 code in your IDE with modern editing features
  2. Git Push: Commit and push changes to the repository
  3. Automated Workflow: Gitea Actions triggers mainframe operations:
    • Uploads source files to PDS members via netcat to the JES card reader
    • Submits JCL jobs for compilation and execution
    • Polls for job completion and retrieves output
    • Archives job output as build artifacts (PDFs)
  4. Sync Management: Deleted files are automatically removed from the mainframe PDS

Architecture

Directory Structure

.
├── .gitea/workflows/      # CI/CD workflow definitions
│   ├── mvs_submit.yaml    # Upload and execute workflow
│   └── mvs_delete.yaml    # PDS member deletion workflow
├── scripts/               # Python automation scripts
│   ├── submit_job.py      # Upload source & submit JCL
│   ├── del_member.py      # Delete PDS members
│   └── poll_job.py        # Poll for job completion
├── src/                   # C90 source files
├── jcl/                   # JCL job control files
└── tmp/                   # Temporary files for workflow execution

Workflows

MVS Submit & Execute (mvs_submit.yaml)

  • Triggers: Push to master with changes in src/ or jcl/
  • Actions:
    • Detects changed .c or .bas files
    • Uploads source to @05054.SRCLIB.C(MEMBER)
    • Submits corresponding JCL from jcl/ directory
    • Polls for job completion (120s timeout)
    • Downloads and archives job output PDF

MVS Delete Members (mvs_delete.yaml)

  • Triggers: Push to master with deletions in src/ or jcl/, or manual dispatch
  • Actions:
    • Detects deleted .c or .bas files
    • Submits IEHPROGM jobs to delete corresponding PDS members
    • Keeps mainframe PDS in sync with repository

Scripts

submit_job.py

  • Uploads source files to MVS PDS using IEBUPDTE
  • Submits JCL jobs via netcat to port 3505 (JES card reader)
  • Handles PDS member creation and updates

del_member.py

  • Deletes PDS members using IEHPROGM utility
  • Maintains sync between repository and mainframe storage

poll_job.py

  • Monitors job completion via MVS console
  • Retrieves job output from remote printout directory
  • Downloads PDF output for archival

Requirements

Mainframe

  • MVS 3.8j TK5 system accessible via network
  • JES card reader port (default: 3505)
  • User account with appropriate permissions

CI/CD Environment

  • Gitea with Actions enabled
  • Ubuntu runner with:
    • netcat-traditional
    • Python 3 with requests library

Configuration Variables

Set in Gitea repository settings:

Variables:

  • MVS_BATCH_PASSWORD: Password for batch job submission
  • MVS_CONSOLE_URL: URL for MVS console access
  • MVS_CONSOLE_USER: Console username
  • LINODE_SSH_HOST: SSH host for printout retrieval
  • LINODE_PRINTOUT_DIR: Remote directory for job output

Secrets:

  • MVS_CONSOLE_PASSWORD: Console password

Usage

Adding New Programs

  1. Create source file in src/ (e.g., HELLO.c)
  2. Create corresponding JCL in jcl/ (e.g., HELLO.jcl)
  3. Commit and push:
    git add src/HELLO.c jcl/HELLO.jcl
    git commit -m "Add HELLO program"
    git push
    
  4. Workflow automatically uploads and executes
  5. Download job output from build artifacts

Removing Programs

Simply delete the source file and push:

git rm src/OLDPROG.c
git commit -m "Remove OLDPROG"
git push

The deletion workflow automatically removes @05054.SRCLIB.C(OLDPROG) from the mainframe.

Manual Cleanup

Trigger the deletion workflow manually via Gitea UI to clean up orphaned PDS members.

Technical Details

Upload Process

Source files are uploaded using JCL with IEBUPDTE:

  1. Python script generates upload JCL dynamically
  2. JCL includes ./ ADD NAME=MEMBER control statements
  3. Source lines are padded to 80 characters (LRECL=80)
  4. Comment lines starting with // or /* are stripped to avoid JCL conflicts
  5. Submitted via netcat to JES internal reader

Deletion Process

PDS members are deleted using IEHPROGM:

//DELMEM   EXEC PGM=IEHPROGM
//DD1      DD DSN=dataset,DISP=SHR
//SYSIN    DD *
  DELETE DSNAME=dataset,MEMBER=member

Job Monitoring

Polls MVS console for job completion, then retrieves PDF output via SSH from remote printout directory.

Development Notes

This project serves as a learning environment for:

  • C90/ANSI C89 programming
  • MVS JCL and utilities (IEBUPDTE, IEHPROGM)
  • Mainframe batch processing workflows
  • CI/CD integration with legacy systems
  • Network protocols for mainframe communication

License

Educational/personal use project.